mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-08-02 21:32:10 +03:00
OmniRoute is an intelligent API gateway that unifies 20+ AI providers behind a single OpenAI-compatible endpoint. Features include intelligent routing with 6 strategies, multi-format translation (OpenAI/Claude/Gemini/Responses API), circuit breakers, semantic caching, combo fallback chains, real-time health monitoring, and a full dashboard with provider management, analytics, and CLI tool integration. Key highlights: - 20+ providers (Claude Code, Codex, Gemini CLI, GitHub Copilot, iFlow, Qwen, Kiro, etc.) - 6 routing strategies (Fill First, Round Robin, P2C, Random, Least Used, Cost Optimized) - Export/Import database backup with full archive support - Translator Playground with 4 modes (Playground, Chat Tester, Test Bench, Live Monitor) - 100% TypeScript across src/ and open-sse/ - Docker support with multi-stage builds - Comprehensive documentation and 9 dashboard screenshots
82 lines
1.8 KiB
TypeScript
82 lines
1.8 KiB
TypeScript
"use client";
|
|
|
|
import { cn } from "@/shared/utils/cn";
|
|
|
|
export default function Avatar({ src, alt = "Avatar", name, size = "md", className }) {
|
|
const sizes = {
|
|
xs: "size-6 text-xs",
|
|
sm: "size-8 text-sm",
|
|
md: "size-10 text-base",
|
|
lg: "size-12 text-lg",
|
|
xl: "size-16 text-xl",
|
|
};
|
|
|
|
// Get initials from name
|
|
const getInitials = (name) => {
|
|
if (!name) return "?";
|
|
const parts = name.split(" ");
|
|
if (parts.length >= 2) {
|
|
return `${parts[0][0]}${parts[1][0]}`.toUpperCase();
|
|
}
|
|
return name.substring(0, 2).toUpperCase();
|
|
};
|
|
|
|
// Generate color from name
|
|
const getColorFromName = (name) => {
|
|
if (!name) return "bg-primary";
|
|
const colors = [
|
|
"bg-red-500",
|
|
"bg-orange-500",
|
|
"bg-amber-500",
|
|
"bg-yellow-500",
|
|
"bg-lime-500",
|
|
"bg-green-500",
|
|
"bg-emerald-500",
|
|
"bg-teal-500",
|
|
"bg-cyan-500",
|
|
"bg-sky-500",
|
|
"bg-blue-500",
|
|
"bg-indigo-500",
|
|
"bg-violet-500",
|
|
"bg-purple-500",
|
|
"bg-fuchsia-500",
|
|
"bg-pink-500",
|
|
"bg-rose-500",
|
|
];
|
|
const index = name.charCodeAt(0) % colors.length;
|
|
return colors[index];
|
|
};
|
|
|
|
if (src) {
|
|
return (
|
|
<div
|
|
className={cn(
|
|
"rounded-full bg-cover bg-center bg-no-repeat",
|
|
"ring-2 ring-white dark:ring-surface-dark shadow-sm",
|
|
sizes[size],
|
|
className
|
|
)}
|
|
style={{ backgroundImage: `url(${src})` }}
|
|
role="img"
|
|
aria-label={alt}
|
|
/>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<div
|
|
className={cn(
|
|
"rounded-full flex items-center justify-center font-semibold text-white",
|
|
"ring-2 ring-white dark:ring-surface-dark shadow-sm",
|
|
sizes[size],
|
|
getColorFromName(name),
|
|
className
|
|
)}
|
|
role="img"
|
|
aria-label={alt}
|
|
>
|
|
{getInitials(name)}
|
|
</div>
|
|
);
|
|
}
|