import React, { useState, useEffect, useRef } from "react"; import Sidebar from "@/components/SettingsSidebar"; import { isMobile } from "react-device-detect"; import System from "@/models/system"; import showToast from "@/utils/toast"; import { useModal } from "@/hooks/useModal"; import CTAButton from "@/components/lib/CTAButton"; import { CaretUpDown, MagnifyingGlass, X } from "@phosphor-icons/react"; import { useTranslation } from "react-i18next"; import PreLoader from "@/components/Preloader"; import ChangeWarningModal from "@/components/ChangeWarning"; import ModalWrapper from "@/components/ModalWrapper"; import VectorDBItem from "@/components/VectorDBSelection/VectorDBItem"; import LanceDbLogo from "@/media/vectordbs/lancedb.png"; import ChromaLogo from "@/media/vectordbs/chroma.png"; import PineconeLogo from "@/media/vectordbs/pinecone.png"; import WeaviateLogo from "@/media/vectordbs/weaviate.png"; import QDrantLogo from "@/media/vectordbs/qdrant.png"; import MilvusLogo from "@/media/vectordbs/milvus.png"; import ZillizLogo from "@/media/vectordbs/zilliz.png"; import AstraDBLogo from "@/media/vectordbs/astraDB.png"; import PGVectorLogo from "@/media/vectordbs/pgvector.png"; import LanceDBOptions from "@/components/VectorDBSelection/LanceDBOptions"; import ChromaDBOptions from "@/components/VectorDBSelection/ChromaDBOptions"; import ChromaCloudOptions from "@/components/VectorDBSelection/ChromaCloudOptions"; import PineconeDBOptions from "@/components/VectorDBSelection/PineconeDBOptions"; import WeaviateDBOptions from "@/components/VectorDBSelection/WeaviateDBOptions"; import QDrantDBOptions from "@/components/VectorDBSelection/QDrantDBOptions"; import MilvusDBOptions from "@/components/VectorDBSelection/MilvusDBOptions"; import ZillizCloudOptions from "@/components/VectorDBSelection/ZillizCloudOptions"; import AstraDBOptions from "@/components/VectorDBSelection/AstraDBOptions"; import PGVectorOptions from "@/components/VectorDBSelection/PGVectorOptions"; export default function GeneralVectorDatabase() { const [saving, setSaving] = useState(false); const [hasChanges, setHasChanges] = useState(false); const [hasEmbeddings, setHasEmbeddings] = useState(false); const [settings, setSettings] = useState({}); const [loading, setLoading] = useState(true); const [searchQuery, setSearchQuery] = useState(""); const [filteredVDBs, setFilteredVDBs] = useState([]); const [selectedVDB, setSelectedVDB] = useState(null); const [searchMenuOpen, setSearchMenuOpen] = useState(false); const searchInputRef = useRef(null); const { isOpen, openModal, closeModal } = useModal(); const { t } = useTranslation(); const handleSubmit = async (e) => { e.preventDefault(); if (selectedVDB !== settings?.VectorDB && hasChanges && hasEmbeddings) { openModal(); } else { await handleSaveSettings(); } }; const handleSaveSettings = async () => { setSaving(true); const form = document.getElementById("vectordb-form"); const settingsData = {}; const formData = new FormData(form); settingsData.VectorDB = selectedVDB; for (var [key, value] of formData.entries()) settingsData[key] = value; const { error } = await System.updateSystem(settingsData); if (error) { showToast(`Failed to save vector database settings: ${error}`, "error"); setHasChanges(true); } else { showToast("Vector database preferences saved successfully.", "success"); setHasChanges(false); } setSaving(false); closeModal(); }; const updateVectorChoice = (selection) => { setSearchQuery(""); setSelectedVDB(selection); setSearchMenuOpen(false); setHasChanges(true); }; const handleXButton = () => { if (searchQuery.length > 0) { setSearchQuery(""); if (searchInputRef.current) searchInputRef.current.value = ""; } else { setSearchMenuOpen(!searchMenuOpen); } }; useEffect(() => { async function fetchKeys() { const _settings = await System.keys(); setSettings(_settings); setSelectedVDB(_settings?.VectorDB || "lancedb"); setHasEmbeddings(_settings?.HasExistingEmbeddings || false); setLoading(false); } fetchKeys(); }, []); useEffect(() => { const filtered = VECTOR_DBS.filter((vdb) => vdb.name.toLowerCase().includes(searchQuery.toLowerCase()) ); setFilteredVDBs(filtered); }, [searchQuery, selectedVDB]); const VECTOR_DBS = [ { name: "LanceDB", value: "lancedb", logo: LanceDbLogo, options: , description: "100% local vector DB that runs on the same instance as AnythingLLM.", }, { name: "PGVector", value: "pgvector", logo: PGVectorLogo, options: , description: "Vector search powered by PostgreSQL.", }, { name: "Chroma", value: "chroma", logo: ChromaLogo, options: , description: "Open source vector database you can host yourself or on the cloud.", }, { name: "Chroma Cloud", value: "chromacloud", logo: ChromaLogo, options: , description: "Fully managed Chroma cloud service with enterprise features and support.", }, { name: "Pinecone", value: "pinecone", logo: PineconeLogo, options: , description: "100% cloud-based vector database for enterprise use cases.", }, { name: "Zilliz Cloud", value: "zilliz", logo: ZillizLogo, options: , description: "Cloud hosted vector database built for enterprise with SOC 2 compliance.", }, { name: "QDrant", value: "qdrant", logo: QDrantLogo, options: , description: "Open source local and distributed cloud vector database.", }, { name: "Weaviate", value: "weaviate", logo: WeaviateLogo, options: , description: "Open source local and cloud hosted multi-modal vector database.", }, { name: "Milvus", value: "milvus", logo: MilvusLogo, options: , description: "Open-source, highly scalable, and blazing fast.", }, { name: "AstraDB", value: "astra", logo: AstraDBLogo, options: , description: "Vector Search for Real-world GenAI.", }, ]; const selectedVDBObject = VECTOR_DBS.find((vdb) => vdb.value === selectedVDB); return (
{loading ? (
) : (

{t("vector.title")}

{t("vector.description")}

{hasChanges && ( handleSubmit()} className="mt-3 mr-0 -mb-14 z-10" > {saving ? t("common.saving") : t("common.save")} )}
{t("vector.provider.title")}
{searchMenuOpen && (
setSearchMenuOpen(false)} /> )} {searchMenuOpen ? (
setSearchQuery(e.target.value)} ref={searchInputRef} onKeyDown={(e) => { if (e.key === "Enter") e.preventDefault(); }} />
{filteredVDBs.map((vdb) => ( updateVectorChoice(vdb.value)} /> ))}
) : ( )}
setHasChanges(true)} className="mt-4 flex flex-col gap-y-1" > {selectedVDB && VECTOR_DBS.find((vdb) => vdb.value === selectedVDB)?.options}
)}
); }