import React, { useRef } from 'react'; import { Link, Pin, PinOff } from 'lucide-react'; import { useQueryClient } from '@tanstack/react-query'; import { OGDialog, OGDialogContent, Button, useToastContext } from '@librechat/client'; import { QueryKeys, Constants, EModelEndpoint, PermissionBits, LocalStorageKeys, AgentListResponse, } from 'librechat-data-provider'; import type t from 'librechat-data-provider'; import { useLocalize, useDefaultConvo, useFavorites } from '~/hooks'; import { renderAgentAvatar, clearMessagesCache } from '~/utils'; import { useChatContext } from '~/Providers'; interface SupportContact { name?: string; email?: string; } interface AgentWithSupport extends t.Agent { support_contact?: SupportContact; } interface AgentDetailProps { agent: AgentWithSupport; // The agent data to display isOpen: boolean; // Whether the detail dialog is open onClose: () => void; // Callback when dialog is closed } /** * Dialog for displaying agent details */ const AgentDetail: React.FC = ({ agent, isOpen, onClose }) => { const localize = useLocalize(); const queryClient = useQueryClient(); const { showToast } = useToastContext(); const dialogRef = useRef(null); const getDefaultConversation = useDefaultConvo(); const { conversation, newConversation } = useChatContext(); const { isFavoriteAgent, toggleFavoriteAgent } = useFavorites(); const isFavorite = isFavoriteAgent(agent?.id); const handleFavoriteClick = () => { if (agent) { toggleFavoriteAgent(agent.id); } }; /** * Navigate to chat with the selected agent */ const handleStartChat = () => { if (agent) { const keys = [QueryKeys.agents, { requiredPermission: PermissionBits.EDIT }]; const listResp = queryClient.getQueryData(keys); if (listResp != null) { if (!listResp.data.some((a) => a.id === agent.id)) { const currentAgents = [agent, ...JSON.parse(JSON.stringify(listResp.data))]; queryClient.setQueryData(keys, { ...listResp, data: currentAgents }); } } localStorage.setItem(`${LocalStorageKeys.AGENT_ID_PREFIX}0`, agent.id); clearMessagesCache(queryClient, conversation?.conversationId); queryClient.invalidateQueries([QueryKeys.messages]); /** Template with agent configuration */ const template = { conversationId: Constants.NEW_CONVO as string, endpoint: EModelEndpoint.agents, agent_id: agent.id, title: localize('com_agents_chat_with', { name: agent.name || localize('com_ui_agent') }), }; const currentConvo = getDefaultConversation({ conversation: { ...(conversation ?? {}), ...template }, preset: template, }); newConversation({ template: currentConvo, preset: template, }); } }; /** * Copy the agent's shareable link to clipboard */ const handleCopyLink = () => { const baseUrl = new URL(window.location.origin); const chatUrl = `${baseUrl.origin}/c/new?agent_id=${agent.id}`; navigator.clipboard .writeText(chatUrl) .then(() => { showToast({ message: localize('com_agents_link_copied'), }); }) .catch(() => { showToast({ message: localize('com_agents_link_copy_failed'), }); }); }; /** * Format contact information with mailto links when appropriate */ const formatContact = () => { if (!agent?.support_contact) return null; const { name, email } = agent.support_contact; if (name && email) { return ( {name} ); } if (email) { return ( {email} ); } if (name) { return {name}; } return null; }; return ( !open && onClose()}> {/* Agent avatar */}
{renderAgentAvatar(agent, { size: 'xl' })}
{/* Agent name */}

{agent?.name || localize('com_agents_loading')}

{/* Contact info */} {agent?.support_contact && formatContact() && (
{localize('com_agents_contact')}: {formatContact()}
)} {/* Agent description */}
{agent?.description}
{/* Action button */}
); }; export default AgentDetail;