diff --git a/src/backend/base/langflow/components/retrievers/SelfQueryRetriever.py b/src/backend/base/langflow/components/retrievers/SelfQueryRetriever.py new file mode 100644 index 000000000..a46bf7bd8 --- /dev/null +++ b/src/backend/base/langflow/components/retrievers/SelfQueryRetriever.py @@ -0,0 +1,39 @@ +# from langflow.field_typing import Data +from langchain.chains.query_constructor.base import AttributeInfo +from langchain.retrievers.self_query.base import SelfQueryRetriever +from langchain_core.vectorstores import VectorStore + +from langflow.custom import CustomComponent +from langflow.field_typing import BaseLanguageModel +from langflow.schema import Record +from langflow.schema.message import Message + + +class SelfQueryRetrieverComponent(CustomComponent): + display_name: str = "Self Query Retriever" + description: str = "Retriever that uses a vector store and an LLM to generate the vector store queries." + icon = "LangChain" + + def build( + self, + query: Message, + vectorstore: VectorStore, + metadata_field_info: list[AttributeInfo], + document_content_description: str, + llm: BaseLanguageModel, + ) -> Record: + metadata_field_info = [i[0] for i in metadata_field_info] + + self_query_retriever = SelfQueryRetriever.from_llm( + llm, + vectorstore, + document_content_description, + metadata_field_info, + enable_limit=True, + ) + + input_text = query.text + documents = self_query_retriever.invoke(input=input_text) + records = [Record.from_document(document) for document in documents] + self.status = records + return records diff --git a/src/frontend/src/icons/LangChain/LangChainIcon.jsx b/src/frontend/src/icons/LangChain/LangChainIcon.jsx new file mode 100644 index 000000000..c68bd3f4f --- /dev/null +++ b/src/frontend/src/icons/LangChain/LangChainIcon.jsx @@ -0,0 +1,10 @@ +const SvgLangChainIcon = (props) => ( + + + + + + + +); +export default SvgLangChainIcon; diff --git a/src/frontend/src/icons/LangChain/index.tsx b/src/frontend/src/icons/LangChain/index.tsx new file mode 100644 index 000000000..48b8566e1 --- /dev/null +++ b/src/frontend/src/icons/LangChain/index.tsx @@ -0,0 +1,9 @@ +import React, { forwardRef } from "react"; +import SvgLangChainIcon from "./LangChainIcon"; + +export const LangChainIcon = forwardRef< + SVGSVGElement, + React.PropsWithChildren<{}> +>((props, ref) => { + return ; +}); diff --git a/src/frontend/src/icons/LangChain/langchain-icon.svg b/src/frontend/src/icons/LangChain/langchain-icon.svg new file mode 100644 index 000000000..e80068b50 --- /dev/null +++ b/src/frontend/src/icons/LangChain/langchain-icon.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/frontend/src/pages/FlowPage/components/PageComponent/index.tsx b/src/frontend/src/pages/FlowPage/components/PageComponent/index.tsx index c78fdf10d..fd2190e53 100644 --- a/src/frontend/src/pages/FlowPage/components/PageComponent/index.tsx +++ b/src/frontend/src/pages/FlowPage/components/PageComponent/index.tsx @@ -180,6 +180,7 @@ export default function Page({ function handleUndo(e: KeyboardEvent) { e.preventDefault(); + e.stopImmediatePropagation(); if (!isWrappedWithClass(e, "noundo")) { undo(); } @@ -187,6 +188,7 @@ export default function Page({ function handleRedo(e: KeyboardEvent) { e.preventDefault(); + e.stopImmediatePropagation(); if (!isWrappedWithClass(e, "noundo")) { redo(); } @@ -194,6 +196,7 @@ export default function Page({ function handleGroup(e: KeyboardEvent) { e.preventDefault(); + e.stopImmediatePropagation(); if (selectionMenuVisible) { handleGroupNode(); } @@ -202,6 +205,7 @@ export default function Page({ function handleDuplicate(e: KeyboardEvent) { e.preventDefault(); e.stopPropagation(); + e.stopImmediatePropagation(); const selectedNode = nodes.filter((obj) => obj.selected); if (selectedNode.length > 0) { paste( @@ -216,6 +220,7 @@ export default function Page({ function handleCopy(e: KeyboardEvent) { e.preventDefault(); + e.stopImmediatePropagation(); if ( !isWrappedWithClass(e, "nocopy") && window.getSelection()?.toString().length === 0 && @@ -227,6 +232,7 @@ export default function Page({ function handleCut(e: KeyboardEvent) { e.preventDefault(); + e.stopImmediatePropagation(); if ( !isWrappedWithClass(e, "nocopy") && window.getSelection()?.toString().length === 0 && @@ -238,6 +244,7 @@ export default function Page({ function handlePaste(e: KeyboardEvent) { e.preventDefault(); + e.stopImmediatePropagation(); if ( !isWrappedWithClass(e, "nocopy") && window.getSelection()?.toString().length === 0 && @@ -253,6 +260,7 @@ export default function Page({ function handleDelete(e: KeyboardEvent) { e.preventDefault(); + e.stopImmediatePropagation(); if (!isWrappedWithClass(e, "nodelete") && lastSelection) { takeSnapshot(); deleteNode(lastSelection.nodes.map((node) => node.id)); diff --git a/src/frontend/src/stores/shortcuts.ts b/src/frontend/src/stores/shortcuts.ts index c0b271849..d792a0d6c 100644 --- a/src/frontend/src/stores/shortcuts.ts +++ b/src/frontend/src/stores/shortcuts.ts @@ -23,7 +23,7 @@ export const useShortcutsStore = create((set, get) => ({ group: "mod+g", cut: "mod+x", paste: "mod+v", - api: "mod+r", + api: "mod+shift+r", update: "mod+u", download: "mod+j", freeze: "mod+f", diff --git a/src/frontend/src/utils/styleUtils.ts b/src/frontend/src/utils/styleUtils.ts index 123702b60..9a65e4f27 100644 --- a/src/frontend/src/utils/styleUtils.ts +++ b/src/frontend/src/utils/styleUtils.ts @@ -1,5 +1,6 @@ import { AlertCircle, + AlertTriangle, ArrowBigUp, ArrowLeft, ArrowUpToLine, @@ -116,7 +117,6 @@ import { Settings, Settings2, Share, - AlertTriangle, Share2, Shield, Sliders, @@ -146,11 +146,10 @@ import { Variable, Wand2, Workflow, + Wrench, X, XCircle, Zap, - PlaySquare, - Wrench, } from "lucide-react"; import { FaApple, FaDiscord, FaGithub } from "react-icons/fa"; import { AWSIcon } from "../icons/AWS"; @@ -177,6 +176,7 @@ import { import { GroqIcon } from "../icons/Groq"; import { HuggingFaceIcon } from "../icons/HuggingFace"; import { IFixIcon } from "../icons/IFixIt"; +import { LangChainIcon } from "../icons/LangChain"; import { MetaIcon } from "../icons/Meta"; import { MidjourneyIcon } from "../icons/Midjorney"; import { MongoDBIcon } from "../icons/MongoDB"; @@ -325,6 +325,7 @@ export const nodeIconsLucide: iconsType = { ChatOllamaModel: OllamaIcon, Faiss: MetaIcon, FaissSearch: MetaIcon, + LangChain: LangChainIcon, AzureOpenAiModel: AzureIcon, Redis: RedisIcon, RedisSearch: RedisIcon,