import { Plus } from 'lucide-react'; import { useCallback, useEffect, useRef } from 'react'; import { Capabilities, defaultAgentFormValues } from 'librechat-data-provider'; import type { AgentCapabilities, AgentForm, TAgentOption } from '~/common'; import type { Agent, AgentCreateParams } from 'librechat-data-provider'; import type { UseMutationResult } from '@tanstack/react-query'; import type { UseFormReset } from 'react-hook-form'; import { cn, createDropdownSetter, createProviderOption, processAgentOption } from '~/utils'; import { useListAgentsQuery, useGetAgentByIdQuery } from '~/data-provider'; import SelectDropDown from '~/components/ui/SelectDropDown'; // import { useFileMapContext } from '~/Providers'; import { useLocalize } from '~/hooks'; const keys = new Set(Object.keys(defaultAgentFormValues)); export default function AgentSelect({ reset, value: currentAgentValue, selectedAgentId, setCurrentAgentId, createMutation, }: { reset: UseFormReset; value?: TAgentOption; selectedAgentId: string | null; setCurrentAgentId: React.Dispatch>; createMutation: UseMutationResult; }) { const localize = useLocalize(); // TODO: file handling for agents // const fileMap = useFileMapContext(); const lastSelectedAgent = useRef(null); const { data: agents = [] } = useListAgentsQuery(undefined, { select: (res) => res.data.map((agent) => processAgentOption(agent /*, fileMap */)), }); const agentQuery = useGetAgentByIdQuery(selectedAgentId ?? '', { enabled: !!selectedAgentId, }); const resetAgentForm = useCallback( (fullAgent: Agent) => { const update = { ...fullAgent, provider: createProviderOption(fullAgent.provider), label: fullAgent.name ?? '', value: fullAgent.id ?? '', }; const actions: AgentCapabilities = { [Capabilities.code_interpreter]: false, [Capabilities.image_vision]: false, [Capabilities.retrieval]: false, }; const formValues: Partial = { ...actions, agent: update, model: update.model, tools: update.tools ?? [], }; Object.entries(fullAgent).forEach(([name, value]) => { if (name === 'model_parameters') { formValues[name] = value; return; } if (!keys.has(name)) { return; } if (typeof value !== 'number' && typeof value !== 'object') { formValues[name] = value; } }); reset(formValues); }, [reset], ); const onSelect = useCallback( (selectedId: string) => { const agentExists = !!(selectedId ? agents.find((agent) => agent.id === selectedId) : undefined); createMutation.reset(); if (!agentExists) { setCurrentAgentId(undefined); return reset({ ...defaultAgentFormValues, }); } setCurrentAgentId(selectedId); const agent = agentQuery.data; if (!agent) { console.warn('Agent not found'); return; } resetAgentForm(agent); }, [agents, createMutation, setCurrentAgentId, agentQuery.data, resetAgentForm, reset], ); useEffect(() => { if (agentQuery.data && agentQuery.isSuccess) { resetAgentForm(agentQuery.data); } }, [agentQuery.data, agentQuery.isSuccess, resetAgentForm]); useEffect(() => { let timerId: NodeJS.Timeout | null = null; if (selectedAgentId === lastSelectedAgent.current) { return; } if (selectedAgentId && agents) { timerId = setTimeout(() => { lastSelectedAgent.current = selectedAgentId; onSelect(selectedAgentId); }, 5); } return () => { if (timerId) { clearTimeout(timerId); } }; }, [selectedAgentId, agents, onSelect]); const createAgent = localize('com_ui_create') + ' ' + localize('com_ui_agent'); const hasAgentValue = !!(typeof currentAgentValue === 'object' ? currentAgentValue.value : currentAgentValue); return ( ( {createAgent} )} /> ); }