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,