mirror of
https://github.com/MODSetter/SurfSense.git
synced 2026-07-18 23:11:12 +02:00
feat: add Agent Model Manager component for managing LLM configurations and enhance UI in related components
This commit is contained in:
parent
f22d7434ce
commit
2b40592f0b
9 changed files with 31 additions and 31 deletions
|
|
@ -42,7 +42,7 @@ import { useMediaQuery } from "@/hooks/use-media-query";
|
||||||
import { getProviderIcon } from "@/lib/provider-icons";
|
import { getProviderIcon } from "@/lib/provider-icons";
|
||||||
import { cn } from "@/lib/utils";
|
import { cn } from "@/lib/utils";
|
||||||
|
|
||||||
interface ModelConfigManagerProps {
|
interface AgentModelManagerProps {
|
||||||
searchSpaceId: number;
|
searchSpaceId: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -54,7 +54,7 @@ function getInitials(name: string): string {
|
||||||
return name.slice(0, 2).toUpperCase();
|
return name.slice(0, 2).toUpperCase();
|
||||||
}
|
}
|
||||||
|
|
||||||
export function ModelConfigManager({ searchSpaceId }: ModelConfigManagerProps) {
|
export function AgentModelManager({ searchSpaceId }: AgentModelManagerProps) {
|
||||||
const isDesktop = useMediaQuery("(min-width: 768px)");
|
const isDesktop = useMediaQuery("(min-width: 768px)");
|
||||||
// Mutations
|
// Mutations
|
||||||
const { mutateAsync: deleteConfig, isPending: isDeleting } = useAtomValue(
|
const { mutateAsync: deleteConfig, isPending: isDeleting } = useAtomValue(
|
||||||
|
|
@ -277,7 +277,7 @@ export function ModelConfigManager({ searchSpaceId }: ModelConfigManagerProps) {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{(canUpdate || canDelete) && (
|
{(canUpdate || canDelete) && (
|
||||||
<div className="flex items-center gap-0 shrink-0 sm:w-0 sm:overflow-hidden sm:group-hover:w-auto sm:opacity-0 sm:group-hover:opacity-100 transition-all duration-150">
|
<div className="flex items-center gap-1 shrink-0 sm:w-0 sm:overflow-hidden sm:group-hover:w-auto sm:opacity-0 sm:group-hover:opacity-100 transition-all duration-150">
|
||||||
{canUpdate && (
|
{canUpdate && (
|
||||||
<TooltipProvider>
|
<TooltipProvider>
|
||||||
<Tooltip open={isDesktop ? undefined : false}>
|
<Tooltip open={isDesktop ? undefined : false}>
|
||||||
|
|
@ -286,7 +286,7 @@ export function ModelConfigManager({ searchSpaceId }: ModelConfigManagerProps) {
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
size="icon"
|
size="icon"
|
||||||
onClick={() => openEditDialog(config)}
|
onClick={() => openEditDialog(config)}
|
||||||
className="h-6 w-6 text-muted-foreground hover:text-foreground"
|
className="h-7 w-7 rounded-lg text-muted-foreground hover:text-foreground"
|
||||||
>
|
>
|
||||||
<Edit3 className="h-3 w-3" />
|
<Edit3 className="h-3 w-3" />
|
||||||
</Button>
|
</Button>
|
||||||
|
|
@ -303,7 +303,7 @@ export function ModelConfigManager({ searchSpaceId }: ModelConfigManagerProps) {
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
size="icon"
|
size="icon"
|
||||||
onClick={() => setConfigToDelete(config)}
|
onClick={() => setConfigToDelete(config)}
|
||||||
className="h-6 w-6 text-muted-foreground hover:text-destructive"
|
className="h-7 w-7 rounded-lg text-muted-foreground hover:text-destructive"
|
||||||
>
|
>
|
||||||
<Trash2 className="h-3 w-3" />
|
<Trash2 className="h-3 w-3" />
|
||||||
</Button>
|
</Button>
|
||||||
|
|
@ -341,7 +341,7 @@ export function ModelConfigManager({ searchSpaceId }: ModelConfigManagerProps) {
|
||||||
|
|
||||||
{/* Footer: Date + Creator */}
|
{/* Footer: Date + Creator */}
|
||||||
<div className="flex items-center pt-2 border-t border-border/40 mt-auto">
|
<div className="flex items-center pt-2 border-t border-border/40 mt-auto">
|
||||||
<span className="flex-1 min-w-0 text-[11px] text-muted-foreground/60 truncate">
|
<span className="shrink-0 text-[11px] text-muted-foreground/60 whitespace-nowrap">
|
||||||
{new Date(config.created_at).toLocaleDateString(undefined, {
|
{new Date(config.created_at).toLocaleDateString(undefined, {
|
||||||
year: "numeric",
|
year: "numeric",
|
||||||
month: "short",
|
month: "short",
|
||||||
|
|
@ -354,7 +354,7 @@ export function ModelConfigManager({ searchSpaceId }: ModelConfigManagerProps) {
|
||||||
<TooltipProvider>
|
<TooltipProvider>
|
||||||
<Tooltip open={isDesktop ? undefined : false}>
|
<Tooltip open={isDesktop ? undefined : false}>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<div className="flex-1 min-w-0 flex items-center justify-end gap-1.5 cursor-default">
|
<div className="min-w-0 flex items-center gap-1.5 cursor-default">
|
||||||
<Avatar className="size-4.5 shrink-0">
|
<Avatar className="size-4.5 shrink-0">
|
||||||
{member.avatarUrl && (
|
{member.avatarUrl && (
|
||||||
<AvatarImage src={member.avatarUrl} alt={member.name} />
|
<AvatarImage src={member.avatarUrl} alt={member.name} />
|
||||||
|
|
@ -273,7 +273,7 @@ export function ImageModelManager({ searchSpaceId }: ImageModelManagerProps) {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{(canUpdate || canDelete) && (
|
{(canUpdate || canDelete) && (
|
||||||
<div className="flex items-center gap-0 shrink-0 sm:w-0 sm:overflow-hidden sm:group-hover:w-auto sm:opacity-0 sm:group-hover:opacity-100 transition-all duration-150">
|
<div className="flex items-center gap-1 shrink-0 sm:w-0 sm:overflow-hidden sm:group-hover:w-auto sm:opacity-0 sm:group-hover:opacity-100 transition-all duration-150">
|
||||||
{canUpdate && (
|
{canUpdate && (
|
||||||
<TooltipProvider>
|
<TooltipProvider>
|
||||||
<Tooltip open={isDesktop ? undefined : false}>
|
<Tooltip open={isDesktop ? undefined : false}>
|
||||||
|
|
@ -282,7 +282,7 @@ export function ImageModelManager({ searchSpaceId }: ImageModelManagerProps) {
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
size="icon"
|
size="icon"
|
||||||
onClick={() => openEditDialog(config)}
|
onClick={() => openEditDialog(config)}
|
||||||
className="h-6 w-6 text-muted-foreground hover:text-foreground"
|
className="h-7 w-7 rounded-lg text-muted-foreground hover:text-foreground"
|
||||||
>
|
>
|
||||||
<Edit3 className="h-3 w-3" />
|
<Edit3 className="h-3 w-3" />
|
||||||
</Button>
|
</Button>
|
||||||
|
|
@ -299,7 +299,7 @@ export function ImageModelManager({ searchSpaceId }: ImageModelManagerProps) {
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
size="icon"
|
size="icon"
|
||||||
onClick={() => setConfigToDelete(config)}
|
onClick={() => setConfigToDelete(config)}
|
||||||
className="h-6 w-6 text-muted-foreground hover:text-destructive"
|
className="h-7 w-7 rounded-lg text-muted-foreground hover:text-destructive"
|
||||||
>
|
>
|
||||||
<Trash2 className="h-3 w-3" />
|
<Trash2 className="h-3 w-3" />
|
||||||
</Button>
|
</Button>
|
||||||
|
|
@ -314,7 +314,7 @@ export function ImageModelManager({ searchSpaceId }: ImageModelManagerProps) {
|
||||||
|
|
||||||
{/* Footer: Date + Creator */}
|
{/* Footer: Date + Creator */}
|
||||||
<div className="flex items-center pt-2 border-t border-border/40 mt-auto">
|
<div className="flex items-center pt-2 border-t border-border/40 mt-auto">
|
||||||
<span className="flex-1 min-w-0 text-[11px] text-muted-foreground/60 truncate">
|
<span className="shrink-0 text-[11px] text-muted-foreground/60 whitespace-nowrap">
|
||||||
{new Date(config.created_at).toLocaleDateString(undefined, {
|
{new Date(config.created_at).toLocaleDateString(undefined, {
|
||||||
year: "numeric",
|
year: "numeric",
|
||||||
month: "short",
|
month: "short",
|
||||||
|
|
@ -327,7 +327,7 @@ export function ImageModelManager({ searchSpaceId }: ImageModelManagerProps) {
|
||||||
<TooltipProvider>
|
<TooltipProvider>
|
||||||
<Tooltip open={isDesktop ? undefined : false}>
|
<Tooltip open={isDesktop ? undefined : false}>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<div className="flex-1 min-w-0 flex items-center justify-end gap-1.5 cursor-default">
|
<div className="min-w-0 flex items-center gap-1.5 cursor-default">
|
||||||
<Avatar className="size-4.5 shrink-0">
|
<Avatar className="size-4.5 shrink-0">
|
||||||
{member.avatarUrl && (
|
{member.avatarUrl && (
|
||||||
<AvatarImage src={member.avatarUrl} alt={member.name} />
|
<AvatarImage src={member.avatarUrl} alt={member.name} />
|
||||||
|
|
|
||||||
|
|
@ -25,10 +25,10 @@ const GeneralSettingsManager = dynamic(
|
||||||
})),
|
})),
|
||||||
{ ssr: false }
|
{ ssr: false }
|
||||||
);
|
);
|
||||||
const ModelConfigManager = dynamic(
|
const AgentModelManager = dynamic(
|
||||||
() =>
|
() =>
|
||||||
import("@/components/settings/model-config-manager").then((m) => ({
|
import("@/components/settings/agent-model-manager").then((m) => ({
|
||||||
default: m.ModelConfigManager,
|
default: m.AgentModelManager,
|
||||||
})),
|
})),
|
||||||
{ ssr: false }
|
{ ssr: false }
|
||||||
);
|
);
|
||||||
|
|
@ -88,7 +88,7 @@ export function SearchSpaceSettingsDialog({ searchSpaceId }: SearchSpaceSettings
|
||||||
const navItems = [
|
const navItems = [
|
||||||
{ value: "general", label: t("nav_general"), icon: <CircleUser className="h-4 w-4" /> },
|
{ value: "general", label: t("nav_general"), icon: <CircleUser className="h-4 w-4" /> },
|
||||||
{ value: "roles", label: t("nav_role_assignments"), icon: <ListChecks className="h-4 w-4" /> },
|
{ value: "roles", label: t("nav_role_assignments"), icon: <ListChecks className="h-4 w-4" /> },
|
||||||
{ value: "models", label: t("nav_agent_configs"), icon: <Bot className="h-4 w-4" /> },
|
{ value: "models", label: t("nav_agent_models"), icon: <Bot className="h-4 w-4" /> },
|
||||||
{
|
{
|
||||||
value: "image-models",
|
value: "image-models",
|
||||||
label: t("nav_image_models"),
|
label: t("nav_image_models"),
|
||||||
|
|
@ -115,7 +115,7 @@ export function SearchSpaceSettingsDialog({ searchSpaceId }: SearchSpaceSettings
|
||||||
|
|
||||||
const content: Record<string, React.ReactNode> = {
|
const content: Record<string, React.ReactNode> = {
|
||||||
general: <GeneralSettingsManager searchSpaceId={searchSpaceId} />,
|
general: <GeneralSettingsManager searchSpaceId={searchSpaceId} />,
|
||||||
models: <ModelConfigManager searchSpaceId={searchSpaceId} />,
|
models: <AgentModelManager searchSpaceId={searchSpaceId} />,
|
||||||
roles: <LLMRoleManager searchSpaceId={searchSpaceId} />,
|
roles: <LLMRoleManager searchSpaceId={searchSpaceId} />,
|
||||||
"image-models": <ImageModelManager searchSpaceId={searchSpaceId} />,
|
"image-models": <ImageModelManager searchSpaceId={searchSpaceId} />,
|
||||||
"vision-models": <VisionModelManager searchSpaceId={searchSpaceId} />,
|
"vision-models": <VisionModelManager searchSpaceId={searchSpaceId} />,
|
||||||
|
|
|
||||||
|
|
@ -271,7 +271,7 @@ export function VisionModelManager({ searchSpaceId }: VisionModelManagerProps) {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{(canUpdate || canDelete) && (
|
{(canUpdate || canDelete) && (
|
||||||
<div className="flex items-center gap-0 shrink-0 sm:w-0 sm:overflow-hidden sm:group-hover:w-auto sm:opacity-0 sm:group-hover:opacity-100 transition-all duration-150">
|
<div className="flex items-center gap-1 shrink-0 sm:w-0 sm:overflow-hidden sm:group-hover:w-auto sm:opacity-0 sm:group-hover:opacity-100 transition-all duration-150">
|
||||||
{canUpdate && (
|
{canUpdate && (
|
||||||
<TooltipProvider>
|
<TooltipProvider>
|
||||||
<Tooltip open={isDesktop ? undefined : false}>
|
<Tooltip open={isDesktop ? undefined : false}>
|
||||||
|
|
@ -297,7 +297,7 @@ export function VisionModelManager({ searchSpaceId }: VisionModelManagerProps) {
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
size="icon"
|
size="icon"
|
||||||
onClick={() => setConfigToDelete(config)}
|
onClick={() => setConfigToDelete(config)}
|
||||||
className="h-6 w-6 text-muted-foreground hover:text-destructive"
|
className="h-7 w-7 rounded-lg text-muted-foreground hover:text-destructive"
|
||||||
>
|
>
|
||||||
<Trash2 className="h-3 w-3" />
|
<Trash2 className="h-3 w-3" />
|
||||||
</Button>
|
</Button>
|
||||||
|
|
@ -312,7 +312,7 @@ export function VisionModelManager({ searchSpaceId }: VisionModelManagerProps) {
|
||||||
|
|
||||||
{/* Footer: Date + Creator */}
|
{/* Footer: Date + Creator */}
|
||||||
<div className="flex items-center pt-2 border-t border-border/40 mt-auto">
|
<div className="flex items-center pt-2 border-t border-border/40 mt-auto">
|
||||||
<span className="flex-1 min-w-0 text-[11px] text-muted-foreground/60 truncate">
|
<span className="shrink-0 text-[11px] text-muted-foreground/60 whitespace-nowrap">
|
||||||
{new Date(config.created_at).toLocaleDateString(undefined, {
|
{new Date(config.created_at).toLocaleDateString(undefined, {
|
||||||
year: "numeric",
|
year: "numeric",
|
||||||
month: "short",
|
month: "short",
|
||||||
|
|
@ -325,7 +325,7 @@ export function VisionModelManager({ searchSpaceId }: VisionModelManagerProps) {
|
||||||
<TooltipProvider>
|
<TooltipProvider>
|
||||||
<Tooltip open={isDesktop ? undefined : false}>
|
<Tooltip open={isDesktop ? undefined : false}>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<div className="flex-1 min-w-0 flex items-center justify-end gap-1.5 cursor-default">
|
<div className="min-w-0 flex items-center gap-1.5 cursor-default">
|
||||||
<Avatar className="size-4.5 shrink-0">
|
<Avatar className="size-4.5 shrink-0">
|
||||||
{member.avatarUrl && (
|
{member.avatarUrl && (
|
||||||
<AvatarImage src={member.avatarUrl} alt={member.name} />
|
<AvatarImage src={member.avatarUrl} alt={member.name} />
|
||||||
|
|
|
||||||
|
|
@ -737,8 +737,8 @@
|
||||||
"back_to_app": "Back to app",
|
"back_to_app": "Back to app",
|
||||||
"nav_general": "General",
|
"nav_general": "General",
|
||||||
"nav_general_desc": "Name, description & basic info",
|
"nav_general_desc": "Name, description & basic info",
|
||||||
"nav_agent_configs": "Agent Configs",
|
"nav_agent_models": "Agent Models",
|
||||||
"nav_agent_configs_desc": "Models with prompts & citations",
|
"nav_agent_models_desc": "Models with prompts & citations",
|
||||||
"nav_role_assignments": "Role Assignments",
|
"nav_role_assignments": "Role Assignments",
|
||||||
"nav_role_assignments_desc": "Assign configs to agent roles",
|
"nav_role_assignments_desc": "Assign configs to agent roles",
|
||||||
"nav_image_models": "Image Models",
|
"nav_image_models": "Image Models",
|
||||||
|
|
|
||||||
|
|
@ -737,8 +737,8 @@
|
||||||
"back_to_app": "Volver a la app",
|
"back_to_app": "Volver a la app",
|
||||||
"nav_general": "General",
|
"nav_general": "General",
|
||||||
"nav_general_desc": "Nombre, descripción e información básica",
|
"nav_general_desc": "Nombre, descripción e información básica",
|
||||||
"nav_agent_configs": "Configuraciones de agente",
|
"nav_agent_models": "Modelos de agente",
|
||||||
"nav_agent_configs_desc": "Modelos LLM con prompts y citas",
|
"nav_agent_models_desc": "Modelos LLM con prompts y citas",
|
||||||
"nav_role_assignments": "Asignaciones de roles",
|
"nav_role_assignments": "Asignaciones de roles",
|
||||||
"nav_role_assignments_desc": "Asignar configuraciones a roles de agente",
|
"nav_role_assignments_desc": "Asignar configuraciones a roles de agente",
|
||||||
"nav_image_models": "Modelos de imagen",
|
"nav_image_models": "Modelos de imagen",
|
||||||
|
|
|
||||||
|
|
@ -737,8 +737,8 @@
|
||||||
"back_to_app": "ऐप पर वापस जाएं",
|
"back_to_app": "ऐप पर वापस जाएं",
|
||||||
"nav_general": "सामान्य",
|
"nav_general": "सामान्य",
|
||||||
"nav_general_desc": "नाम, विवरण और बुनियादी जानकारी",
|
"nav_general_desc": "नाम, विवरण और बुनियादी जानकारी",
|
||||||
"nav_agent_configs": "एजेंट कॉन्फ़िगरेशन",
|
"nav_agent_models": "एजेंट मॉडल",
|
||||||
"nav_agent_configs_desc": "प्रॉम्प्ट और उद्धरण के साथ LLM मॉडल",
|
"nav_agent_models_desc": "प्रॉम्प्ट और उद्धरण के साथ LLM मॉडल",
|
||||||
"nav_role_assignments": "भूमिका असाइनमेंट",
|
"nav_role_assignments": "भूमिका असाइनमेंट",
|
||||||
"nav_role_assignments_desc": "एजेंट भूमिकाओं को कॉन्फ़िगरेशन असाइन करें",
|
"nav_role_assignments_desc": "एजेंट भूमिकाओं को कॉन्फ़िगरेशन असाइन करें",
|
||||||
"nav_image_models": "इमेज मॉडल",
|
"nav_image_models": "इमेज मॉडल",
|
||||||
|
|
|
||||||
|
|
@ -737,8 +737,8 @@
|
||||||
"back_to_app": "Voltar ao app",
|
"back_to_app": "Voltar ao app",
|
||||||
"nav_general": "Geral",
|
"nav_general": "Geral",
|
||||||
"nav_general_desc": "Nome, descrição e informações básicas",
|
"nav_general_desc": "Nome, descrição e informações básicas",
|
||||||
"nav_agent_configs": "Configurações do agente",
|
"nav_agent_models": "Modelos do agente",
|
||||||
"nav_agent_configs_desc": "Modelos LLM com prompts e citações",
|
"nav_agent_models_desc": "Modelos LLM com prompts e citações",
|
||||||
"nav_role_assignments": "Atribuições de funções",
|
"nav_role_assignments": "Atribuições de funções",
|
||||||
"nav_role_assignments_desc": "Atribuir configurações a funções do agente",
|
"nav_role_assignments_desc": "Atribuir configurações a funções do agente",
|
||||||
"nav_image_models": "Modelos de imagem",
|
"nav_image_models": "Modelos de imagem",
|
||||||
|
|
|
||||||
|
|
@ -721,8 +721,8 @@
|
||||||
"back_to_app": "返回应用",
|
"back_to_app": "返回应用",
|
||||||
"nav_general": "常规",
|
"nav_general": "常规",
|
||||||
"nav_general_desc": "名称、描述和基本信息",
|
"nav_general_desc": "名称、描述和基本信息",
|
||||||
"nav_agent_configs": "代理配置",
|
"nav_agent_models": "代理模型",
|
||||||
"nav_agent_configs_desc": "LLM 模型配置提示词和引用",
|
"nav_agent_models_desc": "LLM 模型配置提示词和引用",
|
||||||
"nav_role_assignments": "角色分配",
|
"nav_role_assignments": "角色分配",
|
||||||
"nav_role_assignments_desc": "为代理角色分配配置",
|
"nav_role_assignments_desc": "为代理角色分配配置",
|
||||||
"nav_image_models": "图像模型",
|
"nav_image_models": "图像模型",
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue