From b32e4ca8b9bcb012812a0bc5d3249554a18d2322 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Thu, 6 Jul 2023 17:08:28 -0300 Subject: [PATCH 1/7] =?UTF-8?q?=F0=9F=90=9B=20fix(util.py):=20improve=20ty?= =?UTF-8?q?pe=20formatting=20in=20format=5Fdict=20function=20The=20format?= =?UTF-8?q?=5Fdict=20function=20now=20properly=20handles=20different=20var?= =?UTF-8?q?iations=20of=20list=20types=20by=20removing=20unnecessary=20cha?= =?UTF-8?q?racters=20from=20the=20type=20string.=20This=20improves=20the?= =?UTF-8?q?=20consistency=20and=20accuracy=20of=20the=20type=20formatting?= =?UTF-8?q?=20in=20the=20function.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/backend/langflow/utils/util.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/backend/langflow/utils/util.py b/src/backend/langflow/utils/util.py index 4769563bd..c5db6052e 100644 --- a/src/backend/langflow/utils/util.py +++ b/src/backend/langflow/utils/util.py @@ -243,7 +243,11 @@ def format_dict(d, name: Optional[str] = None): # Check for list type if "List" in _type or "Sequence" in _type or "Set" in _type: - _type = _type.replace("List[", "")[:-1] + _type = ( + _type.replace("List[", "") + .replace("Sequence[", "") + .replace("Set[", "")[:-1] + ) value["list"] = True else: value["list"] = False From 9f80af8f8370183f6fc3702a563511330017f6c8 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Thu, 6 Jul 2023 17:08:54 -0300 Subject: [PATCH 2/7] =?UTF-8?q?=F0=9F=90=9B=20fix(types.py):=20fix=20missi?= =?UTF-8?q?ng=20return=20statement=20in=20PromptVertex's=20=5Fbuilt=5Fobje?= =?UTF-8?q?ct=5Frepr=20method=20The=20=5Fbuilt=5Fobject=5Frepr=20method=20?= =?UTF-8?q?in=20the=20PromptVertex=20class=20was=20missing=20a=20return=20?= =?UTF-8?q?statement,=20causing=20it=20to=20not=20return=20any=20value.=20?= =?UTF-8?q?This=20fix=20adds=20the=20missing=20return=20statement=20to=20e?= =?UTF-8?q?nsure=20the=20method=20returns=20the=20correct=20value.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/backend/langflow/graph/vertex/types.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backend/langflow/graph/vertex/types.py b/src/backend/langflow/graph/vertex/types.py index b48733e84..a8b38bb3f 100644 --- a/src/backend/langflow/graph/vertex/types.py +++ b/src/backend/langflow/graph/vertex/types.py @@ -208,7 +208,7 @@ class PromptVertex(Vertex): # with the variables filled in return self._built_object.format(**self.artifacts) else: - super()._built_object_repr() + return super()._built_object_repr() class OutputParserVertex(Vertex): From 9094876ed3279a9759815cf03e1951ac163b1ed7 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Thu, 6 Jul 2023 17:09:18 -0300 Subject: [PATCH 3/7] =?UTF-8?q?=E2=9C=A8=20feat(agents/base.py):=20add=20s?= =?UTF-8?q?upport=20for=20creating=20frontend=20nodes=20for=20agents=20?= =?UTF-8?q?=F0=9F=94=A7=20fix(agents/base.py):=20import=20missing=20AgentF?= =?UTF-8?q?rontendNode=20class=20from=20langflow.template.frontend=5Fnode.?= =?UTF-8?q?agents=20=F0=9F=94=A7=20fix(initialize/loading.py):=20pass=20no?= =?UTF-8?q?de=5Ftype=20to=20instantiate=5Fagent=20function=20to=20handle?= =?UTF-8?q?=20creation=20of=20frontend=20nodes=20for=20agents=20?= =?UTF-8?q?=F0=9F=94=A7=20fix(template/frontend=5Fnode/agents.py):=20add?= =?UTF-8?q?=20format=5Ffield=20method=20to=20AgentFrontendNode=20class=20t?= =?UTF-8?q?o=20customize=20field=20behavior=20The=20missing=20import=20sta?= =?UTF-8?q?tement=20for=20the=20AgentFrontendNode=20class=20from=20langflo?= =?UTF-8?q?w.template.frontend=5Fnode.agents=20has=20been=20added=20to=20t?= =?UTF-8?q?he=20base.py=20file.=20Support=20for=20creating=20frontend=20no?= =?UTF-8?q?des=20for=20agents=20has=20been=20added=20to=20the=20AgentCreat?= =?UTF-8?q?or=20class=20in=20the=20base.py=20file.=20The=20instantiate=5Fa?= =?UTF-8?q?gent=20function=20in=20the=20loading.py=20file=20now=20receives?= =?UTF-8?q?=20the=20node=5Ftype=20parameter=20to=20handle=20the=20creation?= =?UTF-8?q?=20of=20frontend=20nodes=20for=20agents.=20The=20AgentFrontendN?= =?UTF-8?q?ode=20class=20in=20the=20agents.py=20file=20now=20includes=20a?= =?UTF-8?q?=20format=5Ffield=20method=20to=20customize=20the=20behavior=20?= =?UTF-8?q?of=20certain=20fields.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/backend/langflow/interface/agents/base.py | 16 +++++++++++++++- .../langflow/interface/initialize/loading.py | 14 ++++++++++++-- .../langflow/template/frontend_node/agents.py | 11 +++++++++++ 3 files changed, 38 insertions(+), 3 deletions(-) diff --git a/src/backend/langflow/interface/agents/base.py b/src/backend/langflow/interface/agents/base.py index d404f845d..b272144bc 100644 --- a/src/backend/langflow/interface/agents/base.py +++ b/src/backend/langflow/interface/agents/base.py @@ -6,13 +6,20 @@ from langflow.custom.customs import get_custom_nodes from langflow.interface.agents.custom import CUSTOM_AGENTS from langflow.interface.base import LangChainTypeCreator from langflow.settings import settings +from langflow.template.frontend_node.agents import AgentFrontendNode from langflow.utils.logger import logger -from langflow.utils.util import build_template_from_class +from langflow.utils.util import build_template_from_class, build_template_from_method class AgentCreator(LangChainTypeCreator): type_name: str = "agents" + from_method_nodes = {"ZeroShotAgent": "from_llm_and_tools"} + + @property + def frontend_node_class(self) -> type[AgentFrontendNode]: + return AgentFrontendNode + @property def type_to_loader_dict(self) -> Dict: if self.type_dict is None: @@ -27,6 +34,13 @@ class AgentCreator(LangChainTypeCreator): try: if name in get_custom_nodes(self.type_name).keys(): return get_custom_nodes(self.type_name)[name] + elif name in self.from_method_nodes: + return build_template_from_method( + name, + type_to_cls_dict=self.type_to_loader_dict, + add_function=True, + method_name=self.from_method_nodes[name], + ) return build_template_from_class( name, self.type_to_loader_dict, add_function=True ) diff --git a/src/backend/langflow/interface/initialize/loading.py b/src/backend/langflow/interface/initialize/loading.py index cd5585656..3c3616dd8 100644 --- a/src/backend/langflow/interface/initialize/loading.py +++ b/src/backend/langflow/interface/initialize/loading.py @@ -15,6 +15,7 @@ from pydantic import ValidationError from langflow.interface.custom_lists import CUSTOM_NODES from langflow.interface.importing.utils import get_function, import_by_type +from langflow.interface.agents.base import agent_creator from langflow.interface.toolkits.base import toolkits_creator from langflow.interface.chains.base import chain_creator from langflow.interface.output_parsers.base import output_parser_creator @@ -61,7 +62,7 @@ def convert_kwargs(params): def instantiate_based_on_type(class_object, base_type, node_type, params): if base_type == "agents": - return instantiate_agent(class_object, params) + return instantiate_agent(node_type, class_object, params) elif base_type == "prompts": return instantiate_prompt(node_type, class_object, params) elif base_type == "tools": @@ -159,7 +160,16 @@ def instantiate_chains(node_type, class_object: Type[Chain], params: Dict): return class_object(**params) -def instantiate_agent(class_object: Type[agent_module.Agent], params: Dict): +def instantiate_agent(node_type, class_object: Type[agent_module.Agent], params: Dict): + if node_type in agent_creator.from_method_nodes: + method = agent_creator.from_method_nodes[node_type] + if class_method := getattr(class_object, method, None): + agent = class_method(**params) + tools = params.get("tools", []) + return AgentExecutor.from_agent_and_tools( + agent=agent, + tools=tools, + ) return load_agent_executor(class_object, params) diff --git a/src/backend/langflow/template/frontend_node/agents.py b/src/backend/langflow/template/frontend_node/agents.py index f692a7d6c..b988cbe20 100644 --- a/src/backend/langflow/template/frontend_node/agents.py +++ b/src/backend/langflow/template/frontend_node/agents.py @@ -13,6 +13,17 @@ NON_CHAT_AGENTS = { } +class AgentFrontendNode(FrontendNode): + @staticmethod + def format_field(field: TemplateField, name: str | None = None) -> None: + if field.name in ["suffix", "prefix"]: + field.show = True + if field.name == "Tools" and name == "ZeroShotAgent": + # field. + field.type_name = "BaseTool" + field.is_list = True + + class SQLAgentNode(FrontendNode): name: str = "SQLAgent" template: Template = Template( From e36027b679016d40d637e1f5336c03754696a6a7 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Thu, 6 Jul 2023 17:10:06 -0300 Subject: [PATCH 4/7] =?UTF-8?q?=F0=9F=94=80=20chore(base.py):=20add=20"Bas?= =?UTF-8?q?eTool"=20to=20the=20base=5Fclasses=20list=20in=20get=5Fsignatur?= =?UTF-8?q?e=20method=20The=20"BaseTool"=20class=20is=20added=20to=20the?= =?UTF-8?q?=20base=5Fclasses=20list=20in=20the=20get=5Fsignature=20method.?= =?UTF-8?q?=20This=20change=20ensures=20that=20the=20"BaseTool"=20class=20?= =?UTF-8?q?is=20considered=20as=20one=20of=20the=20base=20classes=20when?= =?UTF-8?q?=20creating=20a=20tool's=20signature.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/backend/langflow/interface/tools/base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backend/langflow/interface/tools/base.py b/src/backend/langflow/interface/tools/base.py index d6b114e4c..027224a3a 100644 --- a/src/backend/langflow/interface/tools/base.py +++ b/src/backend/langflow/interface/tools/base.py @@ -90,7 +90,7 @@ class ToolCreator(LangChainTypeCreator): def get_signature(self, name: str) -> Optional[Dict]: """Get the signature of a tool.""" - base_classes = ["Tool"] + base_classes = ["Tool", "BaseTool"] fields = [] params = [] tool_params = {} From 86bbdb0c30ac35a397fa22ef01f6842d5c0e73b7 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Thu, 6 Jul 2023 17:10:26 -0300 Subject: [PATCH 5/7] =?UTF-8?q?=F0=9F=90=9B=20fix(tools.py):=20add=20"Base?= =?UTF-8?q?Tool"=20to=20the=20base=5Fclasses=20list=20to=20inherit=20from?= =?UTF-8?q?=20the=20correct=20parent=20class=20The=20"base=5Fclasses"=20li?= =?UTF-8?q?st=20in=20the=20ToolNode=20class=20has=20been=20updated=20to=20?= =?UTF-8?q?include=20"BaseTool"=20in=20addition=20to=20"Tool".=20This=20en?= =?UTF-8?q?sures=20that=20the=20ToolNode=20class=20correctly=20inherits=20?= =?UTF-8?q?from=20the=20BaseTool=20class,=20which=20is=20the=20intended=20?= =?UTF-8?q?parent=20class=20for=20this=20node.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/backend/langflow/template/frontend_node/tools.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backend/langflow/template/frontend_node/tools.py b/src/backend/langflow/template/frontend_node/tools.py index fa3942bd2..6b6903fdc 100644 --- a/src/backend/langflow/template/frontend_node/tools.py +++ b/src/backend/langflow/template/frontend_node/tools.py @@ -53,7 +53,7 @@ class ToolNode(FrontendNode): ], ) description: str = "Converts a chain, agent or function into a tool." - base_classes: list[str] = ["Tool"] + base_classes: list[str] = ["Tool", "BaseTool"] def to_dict(self): return super().to_dict() From ee2278c37eacc03736168f5557b7e1539a8611dc Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Thu, 6 Jul 2023 17:11:05 -0300 Subject: [PATCH 6/7] =?UTF-8?q?=F0=9F=9A=80=20feat(base.py):=20add=20pydan?= =?UTF-8?q?tic=20BaseModel=20as=20a=20base=20class=20for=20FieldFormatter?= =?UTF-8?q?=20to=20enable=20data=20validation=20and=20serialization=20The?= =?UTF-8?q?=20FieldFormatter=20class=20now=20inherits=20from=20pydantic.Ba?= =?UTF-8?q?seModel=20in=20addition=20to=20ABC=20(Abstract=20Base=20Class).?= =?UTF-8?q?=20This=20change=20allows=20FieldFormatter=20instances=20to=20b?= =?UTF-8?q?enefit=20from=20the=20data=20validation=20and=20serialization?= =?UTF-8?q?=20capabilities=20provided=20by=20pydantic,=20improving=20the?= =?UTF-8?q?=20reliability=20and=20maintainability=20of=20the=20code.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/backend/langflow/template/frontend_node/formatter/base.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/backend/langflow/template/frontend_node/formatter/base.py b/src/backend/langflow/template/frontend_node/formatter/base.py index 67e906593..f582bc298 100644 --- a/src/backend/langflow/template/frontend_node/formatter/base.py +++ b/src/backend/langflow/template/frontend_node/formatter/base.py @@ -2,9 +2,10 @@ from abc import ABC, abstractmethod from typing import Optional from langflow.template.field.base import TemplateField +from pydantic import BaseModel -class FieldFormatter(ABC): +class FieldFormatter(BaseModel, ABC): @abstractmethod def format(self, field: TemplateField, name: Optional[str]) -> None: pass From afa1c173791503745c9d6b2c69edf8d38aa1d1eb Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Thu, 6 Jul 2023 17:11:26 -0300 Subject: [PATCH 7/7] =?UTF-8?q?=F0=9F=94=97=20docs(config.yaml):=20update?= =?UTF-8?q?=20documentation=20links=20for=20PromptTemplate=20and=20Charact?= =?UTF-8?q?erTextSplitter=20The=20documentation=20links=20for=20PromptTemp?= =?UTF-8?q?late=20and=20CharacterTextSplitter=20have=20been=20updated=20to?= =?UTF-8?q?=20the=20correct=20URLs.=20This=20ensures=20that=20users=20can?= =?UTF-8?q?=20access=20the=20relevant=20documentation=20for=20these=20comp?= =?UTF-8?q?onents.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/backend/langflow/config.yaml | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/backend/langflow/config.yaml b/src/backend/langflow/config.yaml index d179ee182..032a2f049 100644 --- a/src/backend/langflow/config.yaml +++ b/src/backend/langflow/config.yaml @@ -164,8 +164,6 @@ memories: prompts: PromptTemplate: documentation: "https://python.langchain.com/docs/modules/model_io/prompts/prompt_templates/" - ZeroShotPrompt: - documentation: "https://python.langchain.com/docs/modules/agents/how_to/custom_mrkl_agent" textsplitters: CharacterTextSplitter: documentation: "https://python.langchain.com/docs/modules/data_connection/document_transformers/text_splitters/character_text_splitter"