This commit is contained in:
2026-04-05 00:43:23 +05:30
commit 8be37d3e92
425 changed files with 101853 additions and 0 deletions

View File

@@ -0,0 +1,208 @@
"use client";
import { useEffect, useState } from "react";
import {
fetchGroups,
fetchSignals,
Group,
Signal,
formatRelativeTime,
getSignalIcon,
getSeverityColor,
} from "../lib/api";
function GroupAgentCard({ group, signals, index }: { group: Group; signals: Signal[]; index: number }) {
const recentSignals = signals.slice(0, 3);
const latestTimestamp = signals[0]?.metadata?.timestamp;
const criticalCount = signals.filter(
(s) => s.metadata.severity === "critical" || s.metadata.severity === "high"
).length;
const isActive = group.signal_count > 0;
const statusLabel = isActive ? "ACTIVE" : "IDLE";
const statusBg = isActive ? "rgba(16, 185, 129, 0.1)" : "rgba(168, 140, 251, 0.1)";
const statusColor = isActive ? "#10b981" : "#a88cfb";
const gradients = [
["#a88cfb", "#00daf3"],
["#432390", "#a88cfb"],
["#ee7d77", "#ffb300"],
["#00daf3", "#a88cfb"],
];
const [colorA, colorB] = gradients[index % gradients.length];
return (
<div
className="glass rounded-xl border flex flex-col relative overflow-hidden group card-interactive animate-fade-in-up opacity-0"
style={{ borderColor: "rgba(255,255,255,0.05)", animationDelay: `${index * 100}ms` }}
>
{/* Top gradient bar */}
<div
className="h-1 w-full absolute top-0 left-0 opacity-80"
style={{ background: `linear-gradient(to right, ${colorA}, ${colorB}, transparent)` }}
/>
<div className="p-6 flex flex-col gap-5 w-full h-full mt-1">
{/* Header */}
<div className="flex justify-between items-start">
<div className="space-y-1">
<h4
className="font-bold text-[15px] tracking-wide text-white drop-shadow-md"
style={{ fontFamily: "'Inter Tight', sans-serif" }}
>
{group.group_name.toUpperCase()}
</h4>
<p className="text-[10px] font-mono-data opacity-50" style={{ color: "#a88cfb" }}>
LENS: {group.lens?.toUpperCase() || "UNKNOWN"} · {group.signal_count} signals
</p>
</div>
<span
className="px-2.5 py-0.5 rounded text-[9px] font-bold font-mono-data border uppercase tracking-widest shadow-sm"
style={{
backgroundColor: statusBg,
color: statusColor,
borderColor: `${statusColor}4d`,
}}
>
{statusLabel}
</span>
</div>
{/* Current Task */}
<div
className="p-4 rounded-xl bg-black/40 border shadow-inner"
style={{ borderColor: "rgba(255,255,255,0.03)" }}
>
<p className="text-[9px] uppercase tracking-widest mb-2 text-zinc-500 font-mono-data">
Latest Signal
</p>
<p className="text-[12px] font-medium tracking-wide text-zinc-300 line-clamp-2">
{recentSignals[0]?.document || "No signals yet"}
</p>
</div>
{/* Metrics */}
<div className="grid grid-cols-2 gap-4 py-4 border-y border-white/5">
<div className="flex flex-col gap-1.5">
<p className="text-[9px] uppercase tracking-widest text-zinc-500 font-mono-data">
Total Signals
</p>
<p className="text-[13px] text-zinc-300 font-mono-data">{group.signal_count}</p>
</div>
<div className="flex flex-col gap-1.5">
<p className="text-[9px] uppercase tracking-widest text-zinc-500 font-mono-data">
High Priority
</p>
<p
className="text-[13px] font-mono-data"
style={{ color: criticalCount > 0 ? "#ff6f78" : "#10b981" }}
>
{criticalCount > 0 ? `${criticalCount} alerts` : "all clear"}
</p>
</div>
</div>
{/* Terminal Output - last 3 signals */}
<div className="space-y-3 mt-auto flex-1 flex flex-col">
<div className="flex justify-between items-center opacity-70">
<p className="text-[9px] uppercase tracking-widest text-zinc-400 font-mono-data">
Signal Stream
</p>
<span className="material-symbols-outlined text-[16px] text-zinc-500">terminal</span>
</div>
<div
className="text-[10px] p-4 rounded-xl bg-black/50 border overflow-y-auto font-mono-data shadow-inner flex-1 mt-2"
style={{
borderColor: "rgba(255,255,255,0.03)",
color: "#9ca3af",
minHeight: "5rem",
maxHeight: "7rem",
}}
>
{recentSignals.length === 0 ? (
<p className="opacity-40">no signals yet_</p>
) : (
recentSignals.map((sig, idx) => (
<p key={idx} className="mb-1.5 leading-relaxed">
<span style={{ color: getSeverityColor(sig.metadata.severity), opacity: 0.9 }}>
{sig.metadata.type}:
</span>{" "}
<span className="opacity-70 text-zinc-300">
{sig.document.slice(0, 60)}
{sig.document.length > 60 ? "…" : ""}
</span>
</p>
))
)}
<p className="animate-pulse mt-2 opacity-40">_</p>
</div>
</div>
</div>
</div>
);
}
export default function AgentCards() {
const [groups, setGroups] = useState<Group[]>([]);
const [groupSignals, setGroupSignals] = useState<Record<string, Signal[]>>({});
const [loading, setLoading] = useState(true);
useEffect(() => {
async function load() {
try {
const grps = await fetchGroups();
setGroups(grps);
const sigMap: Record<string, Signal[]> = {};
await Promise.all(
grps.map(async (g) => {
try {
const sigs = await fetchSignals(g.group_id);
sigMap[g.group_id] = sigs;
} catch {
sigMap[g.group_id] = [];
}
})
);
setGroupSignals(sigMap);
} catch {
// ignore
} finally {
setLoading(false);
}
}
load();
}, []);
if (loading) {
return (
<div className="flex items-center justify-center py-20 text-zinc-600 col-span-3">
<span className="material-symbols-outlined animate-spin mr-3">autorenew</span>
Loading groups...
</div>
);
}
if (groups.length === 0) {
return (
<div className="text-center py-20 text-zinc-600 col-span-3">
<span className="material-symbols-outlined text-4xl mb-3 block">group_off</span>
<p>No monitored groups yet.</p>
<p className="text-[11px] mt-2">Connect Telegram groups to see agents here.</p>
</div>
);
}
return (
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6 animate-fade-in-up">
{groups.map((group, idx) => (
<GroupAgentCard
key={group.group_id}
group={group}
signals={groupSignals[group.group_id] || []}
index={idx}
/>
))}
</div>
);
}

View File

@@ -0,0 +1,104 @@
"use client";
import { useEffect, useState } from "react";
import { fetchGroups, fetchAllSignals, Group, Signal } from "../lib/api";
export default function AgentStats() {
const [groups, setGroups] = useState<Group[]>([]);
const [signals, setSignals] = useState<Signal[]>([]);
const [loading, setLoading] = useState(true);
useEffect(() => {
async function load() {
try {
const [grps, all] = await Promise.all([fetchGroups(), fetchAllSignals()]);
setGroups(grps);
setSignals(all.flatMap((g) => g.signals));
} catch {
// ignore
} finally {
setLoading(false);
}
}
load();
}, []);
const totalSignals = groups.reduce((acc, g) => acc + g.signal_count, 0);
const activeGroups = groups.filter((g) => g.signal_count > 0).length;
const criticalSignals = signals.filter(
(s) => s.metadata.severity === "critical" || s.metadata.severity === "high"
).length;
const errorRate =
totalSignals > 0
? `${((criticalSignals / totalSignals) * 100).toFixed(2)}%`
: "0.00%";
const stats = [
{
title: "Active Groups",
value: loading ? "—" : `${activeGroups} / ${groups.length}`,
icon: "memory",
iconColor: "#a88cfb",
},
{
title: "Total Signals",
value: loading ? "—" : totalSignals >= 1000 ? `${(totalSignals / 1000).toFixed(1)}k` : String(totalSignals),
icon: "speed",
iconColor: "#00daf3",
},
{
title: "High Priority",
value: loading ? "—" : `${criticalSignals}`,
icon: "warning",
iconColor: criticalSignals > 0 ? "#ff6f78" : "#10b981",
},
{
title: "Lens Coverage",
value: loading ? "—" : `${[...new Set(groups.map((g) => g.lens).filter(Boolean))].length} types`,
icon: "verified",
iconColor: "#10b981",
},
];
return (
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6 animate-fade-in-scale mb-8">
{stats.map((stat, idx) => (
<div
key={idx}
className="glass p-5 rounded-2xl border border-white/5 relative overflow-hidden group card-interactive flex flex-col justify-between"
style={{
minHeight: "100px",
background: "rgba(20,20,25,0.4)",
backdropFilter: "blur(12px)",
}}
>
<p className="text-[10px] uppercase tracking-widest text-zinc-500 font-mono-data mb-3">
{stat.title}
</p>
<div className="flex flex-row items-end justify-between">
<h3 className="text-2xl font-light tracking-wide text-zinc-200 font-mono-data drop-shadow">
{stat.value.split(" ").map((part, i) => (
<span
key={i}
className={
i % 2 !== 0 && part.match(/[a-zA-Z]/)
? "text-sm ml-1 text-zinc-500"
: ""
}
>
{part}{" "}
</span>
))}
</h3>
<span
className="material-symbols-outlined text-[24px] opacity-90 drop-shadow-md"
style={{ color: stat.iconColor }}
>
{stat.icon}
</span>
</div>
</div>
))}
</div>
);
}

View File

@@ -0,0 +1,30 @@
export default function SystemTicker() {
return (
<div
className="mt-12 p-3.5 rounded-lg overflow-hidden bg-black/20 border"
style={{
borderColor: "rgba(167, 139, 250, 0.05)",
boxShadow: "inset 0 2px 10px rgba(0,0,0,0.1)"
}}
>
<div className="flex items-center gap-4">
<span
className="material-symbols-outlined text-[16px] opacity-80"
style={{ color: "#a88cfb" }}
>
pulse_alert
</span>
<div className="flex-1 overflow-hidden whitespace-nowrap">
<div
className="animate-marquee font-mono-data text-[10px] uppercase tracking-widest pl-[100%]"
style={{ color: "#75757c" }}
>
SYSTEM_UPDATE: Node 14 synchronized. New encryption keys deployed. Agent
'Graph_Builder_02' memory usage spike detected at 14:22:01. Global latency
remains within 40ms threshold.
</div>
</div>
</div>
</div>
);
}

View File

@@ -0,0 +1,82 @@
/* Agent fleet specific CSS */
.glass-card {
background: linear-gradient(180deg, rgba(28, 20, 45, 0.4) 0%, rgba(18, 14, 28, 0.6) 100%);
backdrop-filter: blur(16px);
-webkit-backdrop-filter: blur(16px);
border: 1px solid rgba(167, 139, 250, 0.08);
position: relative;
overflow: hidden;
transition: all 0.4s cubic-bezier(0.16, 1, 0.3, 1);
box-shadow: 0 4px 30px rgba(0, 0, 0, 0.1);
}
.glass-card::before {
content: '';
position: absolute;
left: 0;
top: 0;
height: 100%;
width: 1px;
background: linear-gradient(to bottom, transparent, rgba(167, 139, 250, 0.5), transparent);
opacity: 0;
transition: opacity 0.4s ease;
}
.glass-card:hover {
transform: translateY(-4px);
border-color: rgba(167, 139, 250, 0.2);
box-shadow: 0 10px 40px rgba(167, 139, 250, 0.15), inset 0 0 0 1px rgba(255, 255, 255, 0.02);
}
.glass-card:hover::before {
opacity: 1;
}
.neon-glow-violet {
box-shadow: 0 0 20px rgba(167, 139, 250, 0.15);
}
.font-mono-data {
font-family: 'JetBrains Mono', 'Courier New', monospace;
}
.terminal-scroll::-webkit-scrollbar {
width: 4px;
}
.terminal-scroll::-webkit-scrollbar-thumb {
background: rgba(167, 139, 250, 0.3);
border-radius: 2px;
}
@keyframes agent-marquee {
0% { transform: translateX(100%); }
100% { transform: translateX(-100%); }
}
.animate-marquee {
display: inline-block;
animation: agent-marquee 35s linear infinite;
}
/* Terminal Line Entry Animation */
.terminal-line {
opacity: 0;
animation: fade-in-up 0.5s ease forwards;
}
@keyframes fade-in-up {
from {
opacity: 0;
transform: translateY(4px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.terminal-line:nth-child(1) { animation-delay: 0.2s; }
.terminal-line:nth-child(2) { animation-delay: 0.5s; }
.terminal-line:nth-child(3) { animation-delay: 0.8s; }
.terminal-line:nth-child(4) { animation-delay: 1.1s; }

View File

@@ -0,0 +1,75 @@
import "./agents.css";
import Sidebar from "../components/Sidebar";
import TopBar from "../components/TopBar";
import AgentStats from "./AgentStats";
import AgentCards from "./AgentCards";
import SystemTicker from "./SystemTicker";
export const metadata = {
title: "ThirdEye | Agent Operations",
description: "Agent Fleet Management — ThirdEye Sovereign Protocol",
};
export default function AgentsPage() {
return (
<div className="flex h-screen overflow-hidden bg-[#09090B] text-white" style={{ fontFamily: "'Poppins', sans-serif" }}>
<Sidebar />
<main className="flex-1 ml-[240px] flex flex-col h-screen overflow-hidden">
<TopBar />
{/* Scrollable content */}
<div className="flex-1 overflow-y-auto custom-scrollbar px-10 pb-12 pt-10">
{/* Header & Stats */}
<div className="flex flex-col lg:flex-row justify-between items-start lg:items-end mb-10 gap-6">
<div className="space-y-1">
<h1
className="text-3xl font-black tracking-tighter text-white flex items-center gap-3"
style={{ fontFamily: "'Inter Tight', sans-serif" }}
>
Fleet Management
<span
className="px-2 py-0.5 text-[10px] rounded border font-mono-data tracking-widest uppercase"
style={{
backgroundColor: "rgba(168, 140, 251, 0.1)",
color: "#a88cfb",
borderColor: "rgba(168, 140, 251, 0.2)",
}}
>
Live Status
</span>
</h1>
<p
className="max-w-xl text-sm leading-relaxed"
style={{ color: "#acaab1" }}
>
Active deployment of neural processing agents across ThirdEye node
clusters. Monitoring real-time throughput and cognitive load.
</p>
</div>
<button
className="font-bold text-sm px-6 py-3 rounded-lg flex items-center gap-3 neon-glow-violet active:scale-95 transition-all"
style={{
backgroundColor: "#a88cfb",
color: "#260069",
fontFamily: "'Inter Tight', sans-serif",
}}
>
<span className="material-symbols-outlined text-lg">add_circle</span>
Deploy New Agent
</button>
</div>
{/* Stats Grid */}
<AgentStats />
{/* Agent Cards Grid */}
<AgentCards />
{/* Ticker Section */}
<SystemTicker />
</div>
</main>
</div>
);
}