Release v0.1.0 agent topology and runtime refresh

This commit is contained in:
lpf
2026-03-06 17:44:13 +08:00
parent ac5a1bfcb2
commit 7d9ca89476
34 changed files with 1216 additions and 1462 deletions

View File

@@ -113,7 +113,7 @@ const RecursiveConfig: React.FC<RecursiveConfigProps> = ({ data, labels, path =
if (typeof data !== 'object' || data === null) return null;
return (
<div className="grid grid-cols-1 md:grid-cols-2 gap-x-12 gap-y-10">
<div className="grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-x-10 gap-y-8">
{Object.entries(data).map(([key, value]) => {
const currentPath = path ? `${path}.${key}` : key;
const label = labels[key] || key.replace(/_/g, ' ');

View File

@@ -1,5 +1,5 @@
import React from 'react';
import { LayoutDashboard, MessageSquare, Settings, Clock, Terminal, Zap, FolderOpen, ClipboardList, BrainCircuit, Hash, Bot, Workflow, Boxes } from 'lucide-react';
import { LayoutDashboard, MessageSquare, Settings, Clock, Terminal, Zap, FolderOpen, ClipboardList, BrainCircuit, Hash, Bot, Boxes } from 'lucide-react';
import { useTranslation } from 'react-i18next';
import { useAppContext } from '../context/AppContext';
import NavItem from './NavItem';
@@ -27,7 +27,6 @@ const Sidebar: React.FC = () => {
{ icon: <Clock className="w-5 h-5" />, label: t('cronJobs'), to: '/cron' },
{ icon: <FolderOpen className="w-5 h-5" />, label: t('memory'), to: '/memory' },
{ icon: <Bot className="w-5 h-5" />, label: t('subagentProfiles'), to: '/subagent-profiles' },
{ icon: <Workflow className="w-5 h-5" />, label: t('pipelines'), to: '/pipelines' },
],
},
{

View File

@@ -0,0 +1,104 @@
import React, { useEffect, useRef } from 'react';
export const SpaceParticles: React.FC = () => {
const canvasRef = useRef<HTMLCanvasElement>(null);
useEffect(() => {
const canvas = canvasRef.current;
if (!canvas) return;
const ctx = canvas.getContext('2d');
if (!ctx) return;
let animationFrameId: number;
const particles: Array<{
x: number;
y: number;
size: number;
speedX: number;
speedY: number;
opacity: number;
}> = [];
const resize = () => {
const parent = canvas.parentElement;
if (parent) {
canvas.width = parent.clientWidth;
canvas.height = parent.clientHeight;
}
};
window.addEventListener('resize', resize);
resize();
// Initialize particles
const particleCount = Math.floor((canvas.width * canvas.height) / 12000); // Responsive count
for (let i = 0; i < particleCount; i++) {
particles.push({
x: Math.random() * canvas.width,
y: Math.random() * canvas.height,
size: Math.random() * 1.5 + 0.5,
speedX: (Math.random() - 0.5) * 0.4,
speedY: (Math.random() - 0.5) * 0.4,
opacity: Math.random() * 0.6 + 0.1,
});
}
const draw = () => {
ctx.clearRect(0, 0, canvas.width, canvas.height);
// Draw subtle background gradient
const gradient = ctx.createRadialGradient(
canvas.width / 2, canvas.height / 2, 0,
canvas.width / 2, canvas.height / 2, Math.max(canvas.width, canvas.height)
);
gradient.addColorStop(0, 'rgba(30, 27, 75, 0.15)'); // Deep indigo tint
gradient.addColorStop(1, 'rgba(9, 9, 11, 0.9)'); // Zinc-950
ctx.fillStyle = gradient;
ctx.fillRect(0, 0, canvas.width, canvas.height);
particles.forEach((p) => {
p.x += p.speedX;
p.y += p.speedY;
if (p.x < 0) p.x = canvas.width;
if (p.x > canvas.width) p.x = 0;
if (p.y < 0) p.y = canvas.height;
if (p.y > canvas.height) p.y = 0;
ctx.beginPath();
ctx.arc(p.x, p.y, p.size, 0, Math.PI * 2);
ctx.fillStyle = `rgba(167, 139, 250, ${p.opacity})`; // Violet-400 tint
ctx.fill();
});
// Draw connecting lines if close
ctx.lineWidth = 0.5;
for (let i = 0; i < particles.length; i++) {
for (let j = i + 1; j < particles.length; j++) {
const dx = particles[i].x - particles[j].x;
const dy = particles[i].y - particles[j].y;
const dist = Math.sqrt(dx * dx + dy * dy);
if (dist < 120) {
ctx.beginPath();
ctx.strokeStyle = `rgba(139, 92, 246, ${0.15 * (1 - dist / 120)})`; // Violet-500
ctx.moveTo(particles[i].x, particles[i].y);
ctx.lineTo(particles[j].x, particles[j].y);
ctx.stroke();
}
}
}
animationFrameId = requestAnimationFrame(draw);
};
draw();
return () => {
window.removeEventListener('resize', resize);
cancelAnimationFrame(animationFrameId);
};
}, []);
return <canvas ref={canvasRef} className="absolute inset-0 pointer-events-none z-0 rounded-xl" />;
};