From 691604915afc38a5e25af4e19d7d0dee75e69e60 Mon Sep 17 00:00:00 2001 From: Ibis Prevedello Date: Mon, 3 Apr 2023 16:11:20 -0300 Subject: [PATCH 1/4] refac: change the way chains are loaded and fix tools --- src/backend/langflow/config.yaml | 11 +- src/backend/langflow/graph/base.py | 39 ++-- src/backend/langflow/graph/graph.py | 8 +- .../langflow/interface/agents/custom.py | 7 +- src/backend/langflow/interface/chains/base.py | 20 +- .../langflow/interface/custom_lists.py | 189 ++---------------- .../langflow/interface/importing/utils.py | 3 +- .../langflow/interface/prompts/custom.py | 4 +- src/backend/langflow/interface/run.py | 2 +- src/backend/langflow/interface/tools/base.py | 9 +- .../langflow/interface/tools/constants.py | 18 +- src/backend/langflow/interface/tools/util.py | 24 +-- src/backend/langflow/template/nodes.py | 3 +- 13 files changed, 87 insertions(+), 250 deletions(-) diff --git a/src/backend/langflow/config.yaml b/src/backend/langflow/config.yaml index 08beaae08..3922ed254 100644 --- a/src/backend/langflow/config.yaml +++ b/src/backend/langflow/config.yaml @@ -1,8 +1,8 @@ chains: - LLMChain - LLMMathChain - - LLMChecker - # - ConversationChain + - LLMCheckerChain + - ConversationChain agents: - ZeroShotAgent @@ -31,19 +31,16 @@ wrappers: - RequestsWrapper toolkits: - - OpenAPIToolkit - - JsonToolkit + - OpenAPIToolkit + - JsonToolkit memories: - ConversationBufferMemory embeddings: [] - vectorstores: [] - documentloaders: [] - dev: false diff --git a/src/backend/langflow/graph/base.py b/src/backend/langflow/graph/base.py index 24b8a31c6..ded74ee91 100644 --- a/src/backend/langflow/graph/base.py +++ b/src/backend/langflow/graph/base.py @@ -82,51 +82,44 @@ class Node: continue # If the type is not transformable to a python base class # then we need to get the edge that connects to this node - if value["type"] == "file": + if value.get("type") == "file": # Load the type in value.get('suffixes') using # what is inside value.get('content') # value.get('value') is the file name - type_to_load = value.get("suffixes") file_name = value.get("value") content = value.get("content") + type_to_load = value.get("suffixes") loaded_dict = load_file(file_name, content, type_to_load) params[key] = loaded_dict # We should check if the type is in something not # the opposite - elif value["type"] not in DIRECT_TYPES: + elif value.get("type") not in DIRECT_TYPES: # Get the edge that connects to this node - try: - edge = next( - ( - edge - for edge in self.edges - if edge.target == self - and edge.matched_type in value["type"] - ), - None, - ) + edges = [ + edge + for edge in self.edges + if edge.target == self and edge.matched_type in value["type"] + ] - except Exception as e: - raise e # Get the output of the node that the edge connects to # if the value['list'] is True, then there will be more # than one time setting to params[key] # so we need to append to a list if it exists # or create a new list if it doesn't - if edge is None and value["required"]: - # break line + if value["required"] and not edges: + # If a required parameter is not found, raise an error raise ValueError( f"Required input {key} for module {self.node_type} not found" ) elif value["list"]: - if key not in params: - params[key] = [] - if edge is not None: - params[key].append(edge.source) - elif value["required"] or edge is not None: - params[key] = edge.source + # If this is a list parameter, append all sources to a list + params[key] = [edge.source for edge in edges] + elif edges: + # If a single parameter is found, use its source + params[key] = edges[0].source + elif value["required"] or value.get("value"): params[key] = value["value"] diff --git a/src/backend/langflow/graph/graph.py b/src/backend/langflow/graph/graph.py index 8bd2028ca..022deac95 100644 --- a/src/backend/langflow/graph/graph.py +++ b/src/backend/langflow/graph/graph.py @@ -17,7 +17,8 @@ from langflow.interface.llms.base import llm_creator from langflow.interface.prompts.base import prompt_creator from langflow.interface.toolkits.base import toolkits_creator from langflow.interface.tools.base import tool_creator -from langflow.interface.tools.constants import ALL_TOOLS_NAMES, FILE_TOOLS +from langflow.interface.tools.constants import FILE_TOOLS +from langflow.interface.tools.util import get_tools_dict from langflow.interface.wrappers.base import wrapper_creator from langflow.utils import payload @@ -113,7 +114,10 @@ class Graph: nodes.append(AgentNode(node)) elif node_type in chain_creator.to_list(): nodes.append(ChainNode(node)) - elif node_type in tool_creator.to_list() or node_lc_type in ALL_TOOLS_NAMES: + elif ( + node_type in tool_creator.to_list() + or node_lc_type in get_tools_dict().keys() + ): if node_type in FILE_TOOLS: nodes.append(FileToolNode(node)) nodes.append(ToolNode(node)) diff --git a/src/backend/langflow/interface/agents/custom.py b/src/backend/langflow/interface/agents/custom.py index e5ae77743..64930b28a 100644 --- a/src/backend/langflow/interface/agents/custom.py +++ b/src/backend/langflow/interface/agents/custom.py @@ -1,17 +1,16 @@ from typing import Any, List, Optional from langchain import LLMChain -from langchain.agents import AgentExecutor, ZeroShotAgent +from langchain.agents import AgentExecutor, Tool, ZeroShotAgent, initialize_agent from langchain.agents.agent_toolkits.json.prompt import JSON_PREFIX, JSON_SUFFIX from langchain.agents.agent_toolkits.json.toolkit import JsonToolkit from langchain.agents.agent_toolkits.pandas.prompt import PREFIX as PANDAS_PREFIX from langchain.agents.agent_toolkits.pandas.prompt import SUFFIX as PANDAS_SUFFIX from langchain.agents.mrkl.prompt import FORMAT_INSTRUCTIONS -from langchain.schema import BaseLanguageModel from langchain.llms.base import BaseLLM -from langchain.tools.python.tool import PythonAstREPLTool -from langchain.agents import initialize_agent, Tool from langchain.memory.chat_memory import BaseChatMemory +from langchain.schema import BaseLanguageModel +from langchain.tools.python.tool import PythonAstREPLTool class JsonAgent(AgentExecutor): diff --git a/src/backend/langflow/interface/chains/base.py b/src/backend/langflow/interface/chains/base.py index e24cba99b..715608518 100644 --- a/src/backend/langflow/interface/chains/base.py +++ b/src/backend/langflow/interface/chains/base.py @@ -1,10 +1,9 @@ from typing import Dict, List -from langchain.chains import loading as chains_loading - from langflow.interface.base import LangChainTypeCreator +from langflow.interface.custom_lists import chain_type_to_cls_dict from langflow.settings import settings -from langflow.utils.util import build_template_from_function +from langflow.utils.util import build_template_from_class # Assuming necessary imports for Field, Template, and FrontendNode classes @@ -15,25 +14,20 @@ class ChainCreator(LangChainTypeCreator): @property def type_to_loader_dict(self) -> Dict: if self.type_dict is None: - self.type_dict = chains_loading.type_to_loader_dict + self.type_dict = chain_type_to_cls_dict return self.type_dict def get_signature(self, name: str) -> Dict | None: try: - return build_template_from_function( - name, self.type_to_loader_dict, add_function=True - ) + return build_template_from_class(name, chain_type_to_cls_dict) except ValueError as exc: - raise ValueError("Chain not found") from exc + raise ValueError("Memory not found") from exc def to_list(self) -> List[str]: return [ - chain.__annotations__["return"].__name__ + chain.__name__ for chain in self.type_to_loader_dict.values() - if ( - chain.__annotations__["return"].__name__ in settings.chains - or settings.dev - ) + if chain.__name__ in settings.chains or settings.dev ] diff --git a/src/backend/langflow/interface/custom_lists.py b/src/backend/langflow/interface/custom_lists.py index 32d59619b..e813a5830 100644 --- a/src/backend/langflow/interface/custom_lists.py +++ b/src/backend/langflow/interface/custom_lists.py @@ -1,108 +1,21 @@ from typing import Any ## LLM -from langchain import llms, requests +from langchain import chains, document_loaders, embeddings, llms, memory, requests, vectorstores from langchain.agents import agent_toolkits from langchain.chat_models import ChatOpenAI -## Memory -from langchain import memory - -## Document Loaders -from langchain.document_loaders import ( - AirbyteJSONLoader, - AZLyricsLoader, - CollegeConfidentialLoader, - CoNLLULoader, - CSVLoader, - DirectoryLoader, - EverNoteLoader, - FacebookChatLoader, - GCSDirectoryLoader, - GCSFileLoader, - GitbookLoader, - GoogleApiClient, - GoogleApiYoutubeLoader, - GoogleDriveLoader, - GutenbergLoader, - HNLoader, - IFixitLoader, - IMSDbLoader, - NotebookLoader, - NotionDirectoryLoader, - ObsidianLoader, - OnlinePDFLoader, - PagedPDFSplitter, - PDFMinerLoader, - PyMuPDFLoader, - PyPDFLoader, - ReadTheDocsLoader, - RoamLoader, - S3DirectoryLoader, - S3FileLoader, - SRTLoader, - TelegramChatLoader, - TextLoader, - UnstructuredEmailLoader, - UnstructuredFileIOLoader, - UnstructuredFileLoader, - UnstructuredHTMLLoader, - UnstructuredImageLoader, - UnstructuredMarkdownLoader, - UnstructuredPDFLoader, - # BSHTMLLoader, - UnstructuredPowerPointLoader, - UnstructuredURLLoader, - UnstructuredWordDocumentLoader, - WebBaseLoader, - YoutubeLoader, -) - -## Embeddings -from langchain.embeddings import ( - CohereEmbeddings, - FakeEmbeddings, - HuggingFaceEmbeddings, - HuggingFaceHubEmbeddings, - HuggingFaceInstructEmbeddings, - OpenAIEmbeddings, - SelfHostedEmbeddings, - SelfHostedHuggingFaceEmbeddings, - SelfHostedHuggingFaceInstructEmbeddings, - # SagemakerEndpointEmbeddings, - TensorflowHubEmbeddings, -) - -## Vector Stores -from langchain.vectorstores import ( - FAISS, - AtlasDB, - Chroma, - DeepLake, - ElasticVectorSearch, - Milvus, - OpenSearchVectorSearch, - Pinecone, - Qdrant, - VectorStore, - Weaviate, -) - -## Toolkits from langflow.interface.importing.utils import import_class ## LLM - llm_type_to_cls_dict = llms.type_to_cls_dict llm_type_to_cls_dict["openai-chat"] = ChatOpenAI # type: ignore - ## Chain -# from langchain.chains.loading import type_to_loader_dict -# from langchain.chains.conversation.base import ConversationChain - -# chain_type_to_cls_dict = type_to_loader_dict -# chain_type_to_cls_dict["conversation_chain"] = ConversationChain +chain_type_to_cls_dict: dict[str, Any] = { + chain_name: import_class(f"langchain.chains.{chain_name}") + for chain_name in chains.__all__ +} toolkit_type_to_loader_dict: dict[str, Any] = { toolkit_name: import_class(f"langchain.agents.agent_toolkits.{toolkit_name}") @@ -118,99 +31,33 @@ toolkit_type_to_cls_dict: dict[str, Any] = { if not toolkit_name.islower() } -## Memory - - +## Memories memory_type_to_cls_dict: dict[str, Any] = { memory_name: import_class(f"langchain.memory.{memory_name}") for memory_name in memory.__all__ } - +## Wrappers wrapper_type_to_cls_dict: dict[str, Any] = { wrapper.__name__: wrapper for wrapper in [requests.RequestsWrapper] } ## Embeddings - -embedding_type_to_cls_dict = { - "OpenAIEmbeddings": OpenAIEmbeddings, - "HuggingFaceEmbeddings": HuggingFaceEmbeddings, - "CohereEmbeddings": CohereEmbeddings, - "HuggingFaceHubEmbeddings": HuggingFaceHubEmbeddings, - "TensorflowHubEmbeddings": TensorflowHubEmbeddings, - # "SagemakerEndpointEmbeddings": SagemakerEndpointEmbeddings, - "HuggingFaceInstructEmbeddings": HuggingFaceInstructEmbeddings, - "SelfHostedEmbeddings": SelfHostedEmbeddings, - "SelfHostedHuggingFaceEmbeddings": SelfHostedHuggingFaceEmbeddings, - "SelfHostedHuggingFaceInstructEmbeddings": SelfHostedHuggingFaceInstructEmbeddings, - "FakeEmbeddings": FakeEmbeddings, +embedding_type_to_cls_dict: dict[str, Any] = { + embedding_name: import_class(f"langchain.embeddings.{embedding_name}") + for embedding_name in embeddings.__all__ } ## Vector Stores - -vectorstores_type_to_cls_dict = { - "ElasticVectorSearch": ElasticVectorSearch, - "FAISS": FAISS, - "VectorStore": VectorStore, - "Pinecone": Pinecone, - "Weaviate": Weaviate, - "Qdrant": Qdrant, - "Milvus": Milvus, - "Chroma": Chroma, - "OpenSearchVectorSearch": OpenSearchVectorSearch, - "AtlasDB": AtlasDB, - "DeepLake": DeepLake, +vectorstores_type_to_cls_dict: dict[str, Any] = { + vectorstore_name: import_class(f"langchain.vectorstores.{vectorstore_name}") + for vectorstore_name in vectorstores.__all__ } ## Document Loaders - -documentloaders_type_to_cls_dict = { - "UnstructuredFileLoader": UnstructuredFileLoader, - "UnstructuredFileIOLoader": UnstructuredFileIOLoader, - "UnstructuredURLLoader": UnstructuredURLLoader, - "DirectoryLoader": DirectoryLoader, - "NotionDirectoryLoader": NotionDirectoryLoader, - "ReadTheDocsLoader": ReadTheDocsLoader, - "GoogleDriveLoader": GoogleDriveLoader, - "UnstructuredHTMLLoader": UnstructuredHTMLLoader, - # "BSHTMLLoader": BSHTMLLoader, - "UnstructuredPowerPointLoader": UnstructuredPowerPointLoader, - "UnstructuredWordDocumentLoader": UnstructuredWordDocumentLoader, - "UnstructuredPDFLoader": UnstructuredPDFLoader, - "UnstructuredImageLoader": UnstructuredImageLoader, - "ObsidianLoader": ObsidianLoader, - "UnstructuredEmailLoader": UnstructuredEmailLoader, - "UnstructuredMarkdownLoader": UnstructuredMarkdownLoader, - "RoamLoader": RoamLoader, - "YoutubeLoader": YoutubeLoader, - "S3FileLoader": S3FileLoader, - "TextLoader": TextLoader, - "HNLoader": HNLoader, - "GitbookLoader": GitbookLoader, - "S3DirectoryLoader": S3DirectoryLoader, - "GCSFileLoader": GCSFileLoader, - "GCSDirectoryLoader": GCSDirectoryLoader, - "WebBaseLoader": WebBaseLoader, - "IMSDbLoader": IMSDbLoader, - "AZLyricsLoader": AZLyricsLoader, - "CollegeConfidentialLoader": CollegeConfidentialLoader, - "IFixitLoader": IFixitLoader, - "GutenbergLoader": GutenbergLoader, - "PagedPDFSplitter": PagedPDFSplitter, - "PyPDFLoader": PyPDFLoader, - "EverNoteLoader": EverNoteLoader, - "AirbyteJSONLoader": AirbyteJSONLoader, - "OnlinePDFLoader": OnlinePDFLoader, - "PDFMinerLoader": PDFMinerLoader, - "PyMuPDFLoader": PyMuPDFLoader, - "TelegramChatLoader": TelegramChatLoader, - "SRTLoader": SRTLoader, - "FacebookChatLoader": FacebookChatLoader, - "NotebookLoader": NotebookLoader, - "CoNLLULoader": CoNLLULoader, - "GoogleApiYoutubeLoader": GoogleApiYoutubeLoader, - "GoogleApiClient": GoogleApiClient, - "CSVLoader": CSVLoader, - # "BlackboardLoader", +documentloaders_type_to_cls_dict: dict[str, Any] = { + documentloader_name: import_class( + f"langchain.document_loaders.{documentloader_name}" + ) + for documentloader_name in document_loaders.__all__ } diff --git a/src/backend/langflow/interface/importing/utils.py b/src/backend/langflow/interface/importing/utils.py index 96dadc438..0ada410e4 100644 --- a/src/backend/langflow/interface/importing/utils.py +++ b/src/backend/langflow/interface/importing/utils.py @@ -6,9 +6,10 @@ from typing import Any from langchain import PromptTemplate from langchain.agents import Agent from langchain.chains.base import Chain +from langchain.chat_models.base import BaseChatModel from langchain.llms.base import BaseLLM from langchain.tools import BaseTool -from langchain.chat_models.base import BaseChatModel + from langflow.interface.tools.util import get_tool_by_name diff --git a/src/backend/langflow/interface/prompts/custom.py b/src/backend/langflow/interface/prompts/custom.py index a33e20e1c..d1bb98c62 100644 --- a/src/backend/langflow/interface/prompts/custom.py +++ b/src/backend/langflow/interface/prompts/custom.py @@ -1,11 +1,11 @@ from typing import List, Optional from langchain.prompts import PromptTemplate +from pydantic import root_validator + from langflow.graph.utils import extract_input_variables_from_prompt from langflow.template.base import Template, TemplateField from langflow.template.nodes import PromptTemplateNode -from pydantic import root_validator - CHARACTER_PROMPT = """I want you to act like {character} from {series}. I want you to respond and answer like {character}. do not write any explanations. only answer like {character}. diff --git a/src/backend/langflow/interface/run.py b/src/backend/langflow/interface/run.py index 305a7261a..33183fb73 100644 --- a/src/backend/langflow/interface/run.py +++ b/src/backend/langflow/interface/run.py @@ -1,5 +1,6 @@ import contextlib import io +import logging import re from typing import Any, Dict @@ -7,7 +8,6 @@ from langflow.cache.utils import compute_hash, load_cache, save_cache from langflow.graph.graph import Graph from langflow.interface import loading from langflow.utils import payload -import logging logger = logging.getLogger(__name__) diff --git a/src/backend/langflow/interface/tools/base.py b/src/backend/langflow/interface/tools/base.py index 979e7b8fb..1c9546f5c 100644 --- a/src/backend/langflow/interface/tools/base.py +++ b/src/backend/langflow/interface/tools/base.py @@ -10,7 +10,6 @@ from langchain.agents.load_tools import ( from langflow.custom import customs from langflow.interface.base import LangChainTypeCreator from langflow.interface.tools.constants import ( - ALL_TOOLS_NAMES, CUSTOM_TOOLS, FILE_TOOLS, ) @@ -133,8 +132,8 @@ class ToolCreator(LangChainTypeCreator): tools = [] - for tool in ALL_TOOLS_NAMES: - tool_params = get_tool_params(get_tool_by_name(tool)) + for tool, fcn in get_tools_dict().items(): + tool_params = get_tool_params(fcn) if tool_params and not tool_params.get("name"): tool_params["name"] = tool @@ -145,9 +144,7 @@ class ToolCreator(LangChainTypeCreator): ): tools.append(tool_params["name"]) - # Add Tool - custom_tools = customs.get_custom_nodes("tools") - return tools + list(custom_tools.keys()) + return tools tool_creator = ToolCreator() diff --git a/src/backend/langflow/interface/tools/constants.py b/src/backend/langflow/interface/tools/constants.py index caab662a9..89a6bad01 100644 --- a/src/backend/langflow/interface/tools/constants.py +++ b/src/backend/langflow/interface/tools/constants.py @@ -1,11 +1,21 @@ from langchain.agents import Tool -from langchain.agents.load_tools import get_all_tool_names +from langchain.agents.load_tools import ( + _BASE_TOOLS, + _EXTRA_LLM_TOOLS, + _EXTRA_OPTIONAL_TOOLS, + _LLM_TOOLS, +) from langchain.tools.json.tool import JsonSpec from langflow.interface.custom.types import PythonFunction FILE_TOOLS = {"JsonSpec": JsonSpec} CUSTOM_TOOLS = {"Tool": Tool, "PythonFunction": PythonFunction} -ALL_TOOLS_NAMES = set( - get_all_tool_names() + list(CUSTOM_TOOLS.keys()) + list(FILE_TOOLS.keys()) -) +ALL_TOOLS_NAMES = { + **_BASE_TOOLS, + **_LLM_TOOLS, # type: ignore + **{k: v[0] for k, v in _EXTRA_LLM_TOOLS.items()}, # type: ignore + **{k: v[0] for k, v in _EXTRA_OPTIONAL_TOOLS.items()}, + **CUSTOM_TOOLS, + **FILE_TOOLS, # type: ignore +} diff --git a/src/backend/langflow/interface/tools/util.py b/src/backend/langflow/interface/tools/util.py index 42bc64797..8f8673b6b 100644 --- a/src/backend/langflow/interface/tools/util.py +++ b/src/backend/langflow/interface/tools/util.py @@ -2,28 +2,22 @@ import ast import inspect from typing import Dict, Union -from langchain.agents.load_tools import ( - _BASE_TOOLS, - _EXTRA_LLM_TOOLS, - _EXTRA_OPTIONAL_TOOLS, - _LLM_TOOLS, -) from langchain.agents.tools import Tool -from langflow.interface.tools.constants import CUSTOM_TOOLS, FILE_TOOLS +from langflow.interface.tools.constants import ALL_TOOLS_NAMES def get_tools_dict(): """Get the tools dictionary.""" - return { - **_BASE_TOOLS, - **_LLM_TOOLS, - **{k: v[0] for k, v in _EXTRA_LLM_TOOLS.items()}, - **{k: v[0] for k, v in _EXTRA_OPTIONAL_TOOLS.items()}, - **CUSTOM_TOOLS, - **FILE_TOOLS, - } + all_tools = {} + + for tool, fcn in ALL_TOOLS_NAMES.items(): + if tool_params := get_tool_params(fcn): + tool_name = tool_params.get("name") or str(tool) + all_tools[tool_name] = fcn + + return all_tools def get_tool_by_name(name: str): diff --git a/src/backend/langflow/template/nodes.py b/src/backend/langflow/template/nodes.py index 6bd23d59a..369f1db55 100644 --- a/src/backend/langflow/template/nodes.py +++ b/src/backend/langflow/template/nodes.py @@ -1,9 +1,10 @@ from typing import Optional + +from langchain.agents import loading from langchain.agents.mrkl import prompt from langflow.template.base import FrontendNode, Template, TemplateField from langflow.utils.constants import DEFAULT_PYTHON_FUNCTION -from langchain.agents import loading class ZeroShotPromptNode(FrontendNode): From 23b50d31d285d06afefddff5e9c6751fb497bec7 Mon Sep 17 00:00:00 2001 From: Ibis Prevedello Date: Mon, 3 Apr 2023 17:00:17 -0300 Subject: [PATCH 2/4] refac: fix tool name for test --- src/backend/langflow/__main__.py | 2 +- src/backend/langflow/interface/loading.py | 2 +- src/backend/langflow/interface/run.py | 4 +--- tests/data/basic_example.json | 2 +- 4 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/backend/langflow/__main__.py b/src/backend/langflow/__main__.py index 312285a68..1f16744ae 100644 --- a/src/backend/langflow/__main__.py +++ b/src/backend/langflow/__main__.py @@ -7,7 +7,7 @@ from fastapi.staticfiles import StaticFiles from langflow.main import create_app from langflow.settings import settings -from langflow.utils.logger import configure, logger +from langflow.utils.logger import configure app = typer.Typer() diff --git a/src/backend/langflow/interface/loading.py b/src/backend/langflow/interface/loading.py index aca826502..9a8d28d05 100644 --- a/src/backend/langflow/interface/loading.py +++ b/src/backend/langflow/interface/loading.py @@ -22,7 +22,7 @@ from langflow.interface.agents.custom import CUSTOM_AGENTS from langflow.interface.importing.utils import import_by_type from langflow.interface.toolkits.base import toolkits_creator from langflow.interface.types import get_type_list -from langflow.utils import payload, util, validate +from langflow.utils import util, validate def instantiate_class(node_type: str, base_type: str, params: Dict) -> Any: diff --git a/src/backend/langflow/interface/run.py b/src/backend/langflow/interface/run.py index 7c375471a..53a98a04f 100644 --- a/src/backend/langflow/interface/run.py +++ b/src/backend/langflow/interface/run.py @@ -1,13 +1,11 @@ import contextlib import io -import logging import re -from typing import Any, Dict, List, Tuple +from typing import Any, Dict from langflow.cache.utils import compute_hash, load_cache, save_cache from langflow.graph.graph import Graph from langflow.interface import loading -from langflow.utils import payload from langflow.utils.logger import logger diff --git a/tests/data/basic_example.json b/tests/data/basic_example.json index 369272a6f..dabe16786 100644 --- a/tests/data/basic_example.json +++ b/tests/data/basic_example.json @@ -432,7 +432,7 @@ "placeholder": "", "value": "---" }, - "_type": "google-serper" + "_type": "Serper Search" }, "name": "Serper Search", "description": "A low-cost Google Search API. Useful for when you need to answer questions about current events. Input should be a search query.", From 06f9348a6e143c3417e95feea5b1e76efe3a0e3a Mon Sep 17 00:00:00 2001 From: Gabriel Almeida Date: Mon, 3 Apr 2023 17:13:51 -0300 Subject: [PATCH 3/4] fix: change test according to function changes --- tests/test_cache.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/tests/test_cache.py b/tests/test_cache.py index c52ceb38a..0dcc665f6 100644 --- a/tests/test_cache.py +++ b/tests/test_cache.py @@ -3,7 +3,7 @@ import tempfile from pathlib import Path import pytest -from langflow.cache.utils import PREFIX, compute_hash +from langflow.cache.utils import PREFIX, compute_hash, save_cache from langflow.interface.run import load_langchain_object @@ -42,13 +42,15 @@ def langchain_objects_are_equal(obj1, obj2): def test_cache_creation(basic_data_graph): # Compute hash for the input data_graph - computed_hash = compute_hash(basic_data_graph) - # Call process_graph function to build and cache the langchain_object - _ = load_langchain_object(basic_data_graph) - + is_first_message = True + computed_hash, langchain_object = load_langchain_object( + basic_data_graph, is_first_message=is_first_message + ) + save_cache(computed_hash, langchain_object, is_first_message) # Check if the cache file exists cache_file = Path(tempfile.gettempdir()) / f"{PREFIX}_{computed_hash}.dill" + assert cache_file.exists() From cec6a4197332e77c48a59c39a2ae1eedf129b39e Mon Sep 17 00:00:00 2001 From: Ibis Prevedello Date: Mon, 3 Apr 2023 17:27:41 -0300 Subject: [PATCH 4/4] refac: substitute | by Optional --- src/backend/langflow/graph/base.py | 6 +++--- src/backend/langflow/interface/agents/base.py | 4 ++-- src/backend/langflow/interface/chains/base.py | 4 ++-- src/backend/langflow/interface/documentLoaders/base.py | 4 ++-- src/backend/langflow/interface/embeddings/base.py | 4 ++-- src/backend/langflow/interface/llms/base.py | 4 ++-- src/backend/langflow/interface/memories/base.py | 4 ++-- src/backend/langflow/interface/prompts/base.py | 4 ++-- src/backend/langflow/interface/toolkits/base.py | 4 ++-- src/backend/langflow/interface/tools/base.py | 6 +++--- src/backend/langflow/interface/vectorStore/base.py | 4 ++-- src/backend/langflow/interface/wrappers/base.py | 4 ++-- tests/test_cache.py | 2 +- 13 files changed, 27 insertions(+), 27 deletions(-) diff --git a/src/backend/langflow/graph/base.py b/src/backend/langflow/graph/base.py index 837dd4735..fa93ed8ed 100644 --- a/src/backend/langflow/graph/base.py +++ b/src/backend/langflow/graph/base.py @@ -5,7 +5,7 @@ import types from copy import deepcopy -from typing import Any, Dict, List +from typing import Any, Dict, List, Optional from langflow.graph.constants import DIRECT_TYPES from langflow.graph.utils import load_file @@ -15,11 +15,11 @@ from langflow.utils.logger import logger class Node: - def __init__(self, data: Dict, base_type: str | None = None) -> None: + def __init__(self, data: Dict, base_type: Optional[str] = None) -> None: self.id: str = data["id"] self._data = data self.edges: List[Edge] = [] - self.base_type: str | None = base_type + self.base_type: Optional[str] = base_type self._parse_data() self._built_object = None self._built = False diff --git a/src/backend/langflow/interface/agents/base.py b/src/backend/langflow/interface/agents/base.py index 464c04276..94cab1411 100644 --- a/src/backend/langflow/interface/agents/base.py +++ b/src/backend/langflow/interface/agents/base.py @@ -1,4 +1,4 @@ -from typing import Dict, List +from typing import Dict, List, Optional from langchain.agents import loading @@ -21,7 +21,7 @@ class AgentCreator(LangChainTypeCreator): self.type_dict[name] = agent return self.type_dict - def get_signature(self, name: str) -> Dict | None: + def get_signature(self, name: str) -> Optional[Dict]: try: if name in get_custom_nodes(self.type_name).keys(): return get_custom_nodes(self.type_name)[name] diff --git a/src/backend/langflow/interface/chains/base.py b/src/backend/langflow/interface/chains/base.py index 715608518..36542b7d4 100644 --- a/src/backend/langflow/interface/chains/base.py +++ b/src/backend/langflow/interface/chains/base.py @@ -1,4 +1,4 @@ -from typing import Dict, List +from typing import Dict, List, Optional from langflow.interface.base import LangChainTypeCreator from langflow.interface.custom_lists import chain_type_to_cls_dict @@ -17,7 +17,7 @@ class ChainCreator(LangChainTypeCreator): self.type_dict = chain_type_to_cls_dict return self.type_dict - def get_signature(self, name: str) -> Dict | None: + def get_signature(self, name: str) -> Optional[Dict]: try: return build_template_from_class(name, chain_type_to_cls_dict) except ValueError as exc: diff --git a/src/backend/langflow/interface/documentLoaders/base.py b/src/backend/langflow/interface/documentLoaders/base.py index 494fabfd3..844820d7b 100644 --- a/src/backend/langflow/interface/documentLoaders/base.py +++ b/src/backend/langflow/interface/documentLoaders/base.py @@ -1,4 +1,4 @@ -from typing import Dict, List +from typing import Dict, List, Optional from langflow.interface.base import LangChainTypeCreator from langflow.interface.custom_lists import documentloaders_type_to_cls_dict @@ -13,7 +13,7 @@ class DocumentLoaderCreator(LangChainTypeCreator): def type_to_loader_dict(self) -> Dict: return documentloaders_type_to_cls_dict - def get_signature(self, name: str) -> Dict | None: + def get_signature(self, name: str) -> Optional[Dict]: """Get the signature of a document loader.""" try: return build_template_from_class(name, documentloaders_type_to_cls_dict) diff --git a/src/backend/langflow/interface/embeddings/base.py b/src/backend/langflow/interface/embeddings/base.py index de1921b5e..25038a8a5 100644 --- a/src/backend/langflow/interface/embeddings/base.py +++ b/src/backend/langflow/interface/embeddings/base.py @@ -1,4 +1,4 @@ -from typing import Dict, List +from typing import Dict, List, Optional from langflow.interface.base import LangChainTypeCreator from langflow.interface.custom_lists import embedding_type_to_cls_dict @@ -13,7 +13,7 @@ class EmbeddingCreator(LangChainTypeCreator): def type_to_loader_dict(self) -> Dict: return embedding_type_to_cls_dict - def get_signature(self, name: str) -> Dict | None: + def get_signature(self, name: str) -> Optional[Dict]: """Get the signature of an embedding.""" try: return build_template_from_class(name, embedding_type_to_cls_dict) diff --git a/src/backend/langflow/interface/llms/base.py b/src/backend/langflow/interface/llms/base.py index 688845301..85f9035db 100644 --- a/src/backend/langflow/interface/llms/base.py +++ b/src/backend/langflow/interface/llms/base.py @@ -1,4 +1,4 @@ -from typing import Dict, List +from typing import Dict, List, Optional from langflow.interface.base import LangChainTypeCreator from langflow.interface.custom_lists import llm_type_to_cls_dict @@ -15,7 +15,7 @@ class LLMCreator(LangChainTypeCreator): self.type_dict = llm_type_to_cls_dict return self.type_dict - def get_signature(self, name: str) -> Dict | None: + def get_signature(self, name: str) -> Optional[Dict]: """Get the signature of an llm.""" try: return build_template_from_class(name, llm_type_to_cls_dict) diff --git a/src/backend/langflow/interface/memories/base.py b/src/backend/langflow/interface/memories/base.py index 99af98a1b..1bb4b054b 100644 --- a/src/backend/langflow/interface/memories/base.py +++ b/src/backend/langflow/interface/memories/base.py @@ -1,4 +1,4 @@ -from typing import Dict, List +from typing import Dict, List, Optional from langflow.interface.base import LangChainTypeCreator from langflow.interface.custom_lists import memory_type_to_cls_dict @@ -15,7 +15,7 @@ class MemoryCreator(LangChainTypeCreator): self.type_dict = memory_type_to_cls_dict return self.type_dict - def get_signature(self, name: str) -> Dict | None: + def get_signature(self, name: str) -> Optional[Dict]: """Get the signature of a memory.""" try: return build_template_from_class(name, memory_type_to_cls_dict) diff --git a/src/backend/langflow/interface/prompts/base.py b/src/backend/langflow/interface/prompts/base.py index f730481a9..597848b9c 100644 --- a/src/backend/langflow/interface/prompts/base.py +++ b/src/backend/langflow/interface/prompts/base.py @@ -1,4 +1,4 @@ -from typing import Dict, List +from typing import Dict, List, Optional from langchain.prompts import loading @@ -17,7 +17,7 @@ class PromptCreator(LangChainTypeCreator): self.type_dict = loading.type_to_loader_dict return self.type_dict - def get_signature(self, name: str) -> Dict | None: + def get_signature(self, name: str) -> Optional[Dict]: try: if name in get_custom_nodes(self.type_name).keys(): return get_custom_nodes(self.type_name)[name] diff --git a/src/backend/langflow/interface/toolkits/base.py b/src/backend/langflow/interface/toolkits/base.py index c78a9c051..5346ae4b5 100644 --- a/src/backend/langflow/interface/toolkits/base.py +++ b/src/backend/langflow/interface/toolkits/base.py @@ -1,4 +1,4 @@ -from typing import Callable, Dict, List +from typing import Callable, Dict, List, Optional from langchain.agents import agent_toolkits @@ -39,7 +39,7 @@ class ToolkitCreator(LangChainTypeCreator): return self.type_dict - def get_signature(self, name: str) -> Dict | None: + def get_signature(self, name: str) -> Optional[Dict]: try: return build_template_from_class(name, self.type_to_loader_dict) except ValueError as exc: diff --git a/src/backend/langflow/interface/tools/base.py b/src/backend/langflow/interface/tools/base.py index 1c9546f5c..4989a7d4b 100644 --- a/src/backend/langflow/interface/tools/base.py +++ b/src/backend/langflow/interface/tools/base.py @@ -1,4 +1,4 @@ -from typing import Dict, List +from typing import Dict, List, Optional from langchain.agents.load_tools import ( _BASE_TOOLS, @@ -59,7 +59,7 @@ TOOL_INPUTS = { class ToolCreator(LangChainTypeCreator): type_name: str = "tools" - tools_dict: Dict | None = None + tools_dict: Optional[Dict] = None @property def type_to_loader_dict(self) -> Dict: @@ -67,7 +67,7 @@ class ToolCreator(LangChainTypeCreator): self.tools_dict = get_tools_dict() return self.tools_dict - def get_signature(self, name: str) -> Dict | None: + def get_signature(self, name: str) -> Optional[Dict]: """Get the signature of a tool.""" base_classes = ["Tool"] diff --git a/src/backend/langflow/interface/vectorStore/base.py b/src/backend/langflow/interface/vectorStore/base.py index 01c222e07..6c2baa86d 100644 --- a/src/backend/langflow/interface/vectorStore/base.py +++ b/src/backend/langflow/interface/vectorStore/base.py @@ -1,4 +1,4 @@ -from typing import Dict, List +from typing import Dict, List, Optional from langflow.interface.base import LangChainTypeCreator from langflow.interface.custom_lists import vectorstores_type_to_cls_dict @@ -13,7 +13,7 @@ class VectorstoreCreator(LangChainTypeCreator): def type_to_loader_dict(self) -> Dict: return vectorstores_type_to_cls_dict - def get_signature(self, name: str) -> Dict | None: + def get_signature(self, name: str) -> Optional[Dict]: """Get the signature of an embedding.""" try: return build_template_from_class(name, vectorstores_type_to_cls_dict) diff --git a/src/backend/langflow/interface/wrappers/base.py b/src/backend/langflow/interface/wrappers/base.py index abfa559a1..8c5978013 100644 --- a/src/backend/langflow/interface/wrappers/base.py +++ b/src/backend/langflow/interface/wrappers/base.py @@ -1,4 +1,4 @@ -from typing import Dict, List +from typing import Dict, List, Optional from langchain import requests @@ -17,7 +17,7 @@ class WrapperCreator(LangChainTypeCreator): } return self.type_dict - def get_signature(self, name: str) -> Dict | None: + def get_signature(self, name: str) -> Optional[Dict]: try: return build_template_from_class(name, self.type_to_loader_dict) except ValueError as exc: diff --git a/tests/test_cache.py b/tests/test_cache.py index 0dcc665f6..85559bc7b 100644 --- a/tests/test_cache.py +++ b/tests/test_cache.py @@ -3,7 +3,7 @@ import tempfile from pathlib import Path import pytest -from langflow.cache.utils import PREFIX, compute_hash, save_cache +from langflow.cache.utils import PREFIX, save_cache from langflow.interface.run import load_langchain_object