import React, { useMemo } from 'react';
import { useRecoilValue } from 'recoil';
import { OGDialog, OGDialogTemplate } from '@librechat/client';
import {
EToolResources,
EModelEndpoint,
defaultAgentCapabilities,
isDocumentSupportedProvider,
} from 'librechat-data-provider';
import {
ImageUpIcon,
FileSearch,
FileType2Icon,
FileImageIcon,
TerminalSquareIcon,
} from 'lucide-react';
import {
useAgentToolPermissions,
useAgentCapabilities,
useGetAgentsConfig,
useLocalize,
} from '~/hooks';
import { ephemeralAgentByConvoId } from '~/store';
import { useDragDropContext } from '~/Providers';
interface DragDropModalProps {
onOptionSelect: (option: EToolResources | undefined) => void;
files: File[];
isVisible: boolean;
setShowModal: (showModal: boolean) => void;
}
interface FileOption {
label: string;
value?: EToolResources;
icon: React.JSX.Element;
condition?: boolean;
}
const DragDropModal = ({ onOptionSelect, setShowModal, files, isVisible }: DragDropModalProps) => {
const localize = useLocalize();
const { agentsConfig } = useGetAgentsConfig();
/** TODO: Ephemeral Agent Capabilities
* Allow defining agent capabilities on a per-endpoint basis
* Use definition for agents endpoint for ephemeral agents
* */
const capabilities = useAgentCapabilities(agentsConfig?.capabilities ?? defaultAgentCapabilities);
const { conversationId, agentId, endpoint, endpointType } = useDragDropContext();
const ephemeralAgent = useRecoilValue(ephemeralAgentByConvoId(conversationId ?? ''));
const { fileSearchAllowedByAgent, codeAllowedByAgent, provider } = useAgentToolPermissions(
agentId,
ephemeralAgent,
);
const options = useMemo(() => {
const _options: FileOption[] = [];
const currentProvider = provider || endpoint;
// Check if provider supports document upload
if (isDocumentSupportedProvider(currentProvider || endpointType)) {
const isGoogleProvider = currentProvider === EModelEndpoint.google;
const validFileTypes = isGoogleProvider
? files.every(
(file) =>
file.type?.startsWith('image/') ||
file.type?.startsWith('video/') ||
file.type?.startsWith('audio/') ||
file.type === 'application/pdf',
)
: files.every((file) => file.type?.startsWith('image/') || file.type === 'application/pdf');
_options.push({
label: localize('com_ui_upload_provider'),
value: undefined,
icon: ,
condition: validFileTypes,
});
} else {
// Only show image upload option if all files are images and provider doesn't support documents
_options.push({
label: localize('com_ui_upload_image_input'),
value: undefined,
icon: ,
condition: files.every((file) => file.type?.startsWith('image/')),
});
}
if (capabilities.fileSearchEnabled && fileSearchAllowedByAgent) {
_options.push({
label: localize('com_ui_upload_file_search'),
value: EToolResources.file_search,
icon: ,
});
}
if (capabilities.codeEnabled && codeAllowedByAgent) {
_options.push({
label: localize('com_ui_upload_code_files'),
value: EToolResources.execute_code,
icon: ,
});
}
if (capabilities.contextEnabled) {
_options.push({
label: localize('com_ui_upload_ocr_text'),
value: EToolResources.context,
icon: ,
});
}
return _options;
}, [
files,
localize,
provider,
endpoint,
endpointType,
capabilities,
codeAllowedByAgent,
fileSearchAllowedByAgent,
]);
if (!isVisible) {
return null;
}
return (
{options.map(
(option, index) =>
option.condition !== false && (
),
)}
}
/>
);
};
export default DragDropModal;