From fe3f3658851d268d1387cc5de97bd151fbdb7ef2 Mon Sep 17 00:00:00 2001 From: igorrCarvalho Date: Mon, 10 Jun 2024 12:39:39 -0300 Subject: [PATCH 01/11] Fix: use stopImmediatePropagation to prevent macOS bugs --- .../src/pages/FlowPage/components/PageComponent/index.tsx | 8 ++++++++ 1 file changed, 8 insertions(+) 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)); From d0a03b15639e630cf382e524c0cf9f307894a99b Mon Sep 17 00:00:00 2001 From: ogabrielluiz Date: Mon, 10 Jun 2024 12:51:30 -0300 Subject: [PATCH 02/11] feat: Add LangChainIcon component and export it in index.tsx --- src/frontend/src/icons/LangChain/LangChainIcon.jsx | 10 ++++++++++ src/frontend/src/icons/LangChain/index.tsx | 9 +++++++++ src/frontend/src/icons/LangChain/langchain-icon.svg | 5 +++++ src/frontend/src/utils/styleUtils.ts | 7 ++++--- 4 files changed, 28 insertions(+), 3 deletions(-) create mode 100644 src/frontend/src/icons/LangChain/LangChainIcon.jsx create mode 100644 src/frontend/src/icons/LangChain/index.tsx create mode 100644 src/frontend/src/icons/LangChain/langchain-icon.svg 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/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, From 23b2bf2358883efe26e00dba995259dd82fe710f Mon Sep 17 00:00:00 2001 From: ogabrielluiz Date: Mon, 10 Jun 2024 12:59:06 -0300 Subject: [PATCH 03/11] feat: Add SelfQueryRetrieverComponent to langflow retrievers --- .../retrievers/SelfQueryRetriever.py | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 src/backend/base/langflow/components/retrievers/SelfQueryRetriever.py 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 From ed20dd606f91e998493e458eb870ba67c37dfa47 Mon Sep 17 00:00:00 2001 From: ogabrielluiz Date: Mon, 10 Jun 2024 13:07:00 -0300 Subject: [PATCH 04/11] chore: Update keyboard shortcut for API to "mod+shift+r" --- src/frontend/src/stores/shortcuts.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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", From 246ea90b2398bdeb46f2844dd0e078a1eb2ba347 Mon Sep 17 00:00:00 2001 From: cristhianzl Date: Mon, 10 Jun 2024 13:21:10 -0300 Subject: [PATCH 05/11] =?UTF-8?q?=E2=9C=A8=20(tailwind.config.js):=20add?= =?UTF-8?q?=20custom=20focus-visible=20styles=20to=20improve=20accessibili?= =?UTF-8?q?ty=20and=20user=20experience?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/frontend/tailwind.config.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/frontend/tailwind.config.js b/src/frontend/tailwind.config.js index 6f99f7b58..11e9c9d25 100644 --- a/src/frontend/tailwind.config.js +++ b/src/frontend/tailwind.config.js @@ -237,6 +237,10 @@ module.exports = { ".text-align-last-right": { "text-align-last": "right", }, + ":focus-visible": { + outline: "none !important", + outlineOffset: "0px !important", + }, }); }), require("@tailwindcss/typography"), From 65037a43a57cfe11d833be2c9ac492bee8ef5be7 Mon Sep 17 00:00:00 2001 From: ogabrielluiz Date: Mon, 10 Jun 2024 14:11:04 -0300 Subject: [PATCH 06/11] refactor: Update session_id parameter in build_and_cache_graph_from_db function --- src/backend/base/langflow/api/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backend/base/langflow/api/utils.py b/src/backend/base/langflow/api/utils.py index 1dbd68d8f..82bd32165 100644 --- a/src/backend/base/langflow/api/utils.py +++ b/src/backend/base/langflow/api/utils.py @@ -219,7 +219,7 @@ async def build_and_cache_graph_from_db(flow_id: str, session: Session, chat_ser if vertex is None: raise ValueError(f"Vertex {vertex_id} not found") if not vertex._raw_params.get("session_id"): - vertex.update_raw_params({"session_id": flow_id}) + vertex.update_raw_params({"session_id": flow_id}, overwrite=True) await chat_service.set_cache(flow_id, graph) return graph From 6eac507eb9bb64e26931bd5dfe3447b9fff34f56 Mon Sep 17 00:00:00 2001 From: ogabrielluiz Date: Mon, 10 Jun 2024 14:11:43 -0300 Subject: [PATCH 07/11] feat: Update RecordsOutput build method to set status --- .../base/langflow/components/outputs/RecordsOutput.py | 1 + .../outputModal/components/switchOutputView/index.tsx | 2 +- .../src/modals/IOModal/components/IOFieldView/index.tsx | 6 +++++- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/backend/base/langflow/components/outputs/RecordsOutput.py b/src/backend/base/langflow/components/outputs/RecordsOutput.py index c750e675b..cbd268ea6 100644 --- a/src/backend/base/langflow/components/outputs/RecordsOutput.py +++ b/src/backend/base/langflow/components/outputs/RecordsOutput.py @@ -16,4 +16,5 @@ class RecordOutput(CustomComponent): } def build(self, input_value: Record) -> Record: + self.status = input_value return input_value diff --git a/src/frontend/src/CustomNodes/GenericNode/components/outputModal/components/switchOutputView/index.tsx b/src/frontend/src/CustomNodes/GenericNode/components/outputModal/components/switchOutputView/index.tsx index 307c77c1a..437adb511 100644 --- a/src/frontend/src/CustomNodes/GenericNode/components/outputModal/components/switchOutputView/index.tsx +++ b/src/frontend/src/CustomNodes/GenericNode/components/outputModal/components/switchOutputView/index.tsx @@ -28,7 +28,7 @@ export default function SwitchOutputView(nodeId): JSX.Element { if (resultMessage.raw) { resultMessage = resultMessage.raw; } - console.log("resultType", results); + return ( <> diff --git a/src/frontend/src/modals/IOModal/components/IOFieldView/index.tsx b/src/frontend/src/modals/IOModal/components/IOFieldView/index.tsx index 20cf9f691..4de8d0687 100644 --- a/src/frontend/src/modals/IOModal/components/IOFieldView/index.tsx +++ b/src/frontend/src/modals/IOModal/components/IOFieldView/index.tsx @@ -254,7 +254,11 @@ export default function IOFieldView({
artifact.data + ) ?? [] + } columnMode="union" />
From f8aa1274fc87233436930eaf9aa358219b3f13d6 Mon Sep 17 00:00:00 2001 From: ogabrielluiz Date: Mon, 10 Jun 2024 14:12:24 -0300 Subject: [PATCH 08/11] =?UTF-8?q?=E2=9C=A8=20(record.py):=20add=20=5F=5Feq?= =?UTF-8?q?=5F=5F=20method=20to=20compare=20Record=20instances=20based=20o?= =?UTF-8?q?n=20their=20data=20attribute?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/backend/base/langflow/schema/record.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/backend/base/langflow/schema/record.py b/src/backend/base/langflow/schema/record.py index 830f576ba..67d9b5da8 100644 --- a/src/backend/base/langflow/schema/record.py +++ b/src/backend/base/langflow/schema/record.py @@ -1,12 +1,12 @@ import copy import json -from typing import cast, Optional +from typing import Optional, cast from langchain_core.documents import Document from langchain_core.messages import AIMessage, BaseMessage, HumanMessage, SystemMessage +from langchain_core.prompt_values import ImagePromptValue from langchain_core.prompts.image import ImagePromptTemplate from pydantic import BaseModel, model_serializer, model_validator -from langchain_core.prompt_values import ImagePromptValue class Record(BaseModel): @@ -200,3 +200,6 @@ class Record(BaseModel): def __contains__(self, key): return key in self.data + + def __eq__(self, other): + return isinstance(other, Record) and self.data == other.data From 0de6c2a88fb99b4891e09c849c9d39a72af48597 Mon Sep 17 00:00:00 2001 From: ogabrielluiz Date: Mon, 10 Jun 2024 14:12:32 -0300 Subject: [PATCH 09/11] feat: Update Prompt class to assign formatted prompt to self.text --- src/backend/base/langflow/field_typing/prompt.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/backend/base/langflow/field_typing/prompt.py b/src/backend/base/langflow/field_typing/prompt.py index ef6c7ce9a..029261ac7 100644 --- a/src/backend/base/langflow/field_typing/prompt.py +++ b/src/backend/base/langflow/field_typing/prompt.py @@ -25,6 +25,7 @@ class Prompt(Record): prompt_template = PromptTemplate.from_template(self.template) variables_with_str_values = dict_values_to_string(self.variables) formatted_prompt = prompt_template.format(**variables_with_str_values) + self.text = formatted_prompt return formatted_prompt @classmethod From 6c27964edd2213671f3c859653dcb9afb49d1c49 Mon Sep 17 00:00:00 2001 From: ogabrielluiz Date: Mon, 10 Jun 2024 14:12:50 -0300 Subject: [PATCH 10/11] =?UTF-8?q?=F0=9F=90=9B=20(custom=5Fcomponent.py):?= =?UTF-8?q?=20fix=20resolving=20path=20logic=20to=20handle=20empty=20path?= =?UTF-8?q?=20input=20and=20check=20if=20path=20parts=20exist=20before=20a?= =?UTF-8?q?ccessing=20the=20first=20part?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../langflow/custom/custom_component/custom_component.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/backend/base/langflow/custom/custom_component/custom_component.py b/src/backend/base/langflow/custom/custom_component/custom_component.py index 896b07337..5c1da081b 100644 --- a/src/backend/base/langflow/custom/custom_component/custom_component.py +++ b/src/backend/base/langflow/custom/custom_component/custom_component.py @@ -126,8 +126,11 @@ class CustomComponent(Component): @staticmethod def resolve_path(path: str) -> str: """Resolves the path to an absolute path.""" + if not path: + return path path_object = Path(path) - if path_object.parts[0] == "~": + + if path_object.parts and path_object.parts[0] == "~": path_object = path_object.expanduser() elif path_object.is_relative_to("."): path_object = path_object.resolve() From 2f4ebb290a1e5eefddac51f4fd2746cc672d2f9c Mon Sep 17 00:00:00 2001 From: cristhianzl Date: Mon, 10 Jun 2024 14:14:39 -0300 Subject: [PATCH 11/11] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20(TableOptions):=20re?= =?UTF-8?q?order=20imports=20for=20better=20readability=20=F0=9F=92=84=20(?= =?UTF-8?q?TableOptions):=20adjust=20gap=20between=20buttons=20for=20bette?= =?UTF-8?q?r=20UI=20spacing=20=F0=9F=92=84=20(TableOptions):=20update=20ic?= =?UTF-8?q?on=20styles=20for=20better=20visual=20feedback=20=E2=9C=A8=20(e?= =?UTF-8?q?ditNodeModal):=20add=20dark=20mode=20support=20for=20badge=20co?= =?UTF-8?q?mponent=20=E2=99=BB=EF=B8=8F=20(editNodeModal):=20refactor=20fu?= =?UTF-8?q?nction=20parameters=20for=20consistency=20=F0=9F=92=84=20(heade?= =?UTF-8?q?rComponent):=20update=20icon=20hover=20color=20for=20better=20U?= =?UTF-8?q?X=20consistency?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/TableOptions/index.tsx | 13 ++++++++----- src/frontend/src/modals/editNodeModal/index.tsx | 7 ++++++- .../MainPage/components/headerComponent/index.tsx | 2 +- 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/src/frontend/src/components/tableComponent/components/TableOptions/index.tsx b/src/frontend/src/components/tableComponent/components/TableOptions/index.tsx index 7ad2d11f3..dcf246fda 100644 --- a/src/frontend/src/components/tableComponent/components/TableOptions/index.tsx +++ b/src/frontend/src/components/tableComponent/components/TableOptions/index.tsx @@ -1,7 +1,7 @@ import { cn } from "../../../../utils/utils"; +import IconComponent from "../../../genericIconComponent"; import ShadTooltip from "../../../shadTooltipComponent"; import { Button } from "../../../ui/button"; -import IconComponent from "../../../genericIconComponent"; export default function TableOptions({ resetGrid, @@ -18,7 +18,7 @@ export default function TableOptions({ }): JSX.Element { return (
-
+
@@ -81,8 +84,8 @@ export default function TableOptions({ diff --git a/src/frontend/src/modals/editNodeModal/index.tsx b/src/frontend/src/modals/editNodeModal/index.tsx index 4e910ca84..63849cd7e 100644 --- a/src/frontend/src/modals/editNodeModal/index.tsx +++ b/src/frontend/src/modals/editNodeModal/index.tsx @@ -3,6 +3,7 @@ import { forwardRef, useEffect, useRef, useState } from "react"; import IconComponent from "../../components/genericIconComponent"; import TableComponent from "../../components/tableComponent"; import { Badge } from "../../components/ui/badge"; +import { useDarkStore } from "../../stores/darkStore"; import useFlowStore from "../../stores/flowStore"; import { NodeDataType } from "../../types/flow"; import BaseModal from "../baseModal"; @@ -28,6 +29,8 @@ const EditNodeModal = forwardRef( ) => { const myData = useRef(data); + const isDark = useDarkStore((state) => state.dark); + const setNode = useFlowStore((state) => state.setNode); function changeAdvanced(n) { @@ -85,7 +88,9 @@ const EditNodeModal = forwardRef( {data.type} - ID: {data.id} + + ID: {data.id} +
diff --git a/src/frontend/src/pages/MainPage/components/headerComponent/index.tsx b/src/frontend/src/pages/MainPage/components/headerComponent/index.tsx index f4e518e19..151cdd902 100644 --- a/src/frontend/src/pages/MainPage/components/headerComponent/index.tsx +++ b/src/frontend/src/pages/MainPage/components/headerComponent/index.tsx @@ -107,7 +107,7 @@ const HeaderComponent = ({ name="Trash2" className={cn( "h-5 w-5 text-primary transition-all", - disableFunctions ? "" : "hover:text-destructive", + disableFunctions ? "" : "hover:text-status-red", )} />