From 67f8bb9dab66151083743e7a2d5833d9d0e69b22 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Wed, 9 Aug 2023 21:10:31 -0300 Subject: [PATCH 1/8] =?UTF-8?q?=F0=9F=90=9B=20fix(base.py):=20fix=20memory?= =?UTF-8?q?=20inputs=20only=20if=20langchain=5Fobject=20is=20not=20an=20in?= =?UTF-8?q?stance=20of=20AgentExecutor=20to=20prevent=20unnecessary=20fix?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 🔀 chore(base.py): merge changes from langchain.agents.agent module to base module --- src/backend/langflow/processing/base.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/backend/langflow/processing/base.py b/src/backend/langflow/processing/base.py index f1d7b6e56..13ff6a385 100644 --- a/src/backend/langflow/processing/base.py +++ b/src/backend/langflow/processing/base.py @@ -5,6 +5,7 @@ from langflow.api.v1.callback import ( ) from langflow.processing.process import fix_memory_inputs, format_actions from langflow.utils.logger import logger +from langchain.agents.agent import AgentExecutor async def get_result_and_steps(langchain_object, inputs: Union[dict, str], **kwargs): @@ -20,7 +21,8 @@ async def get_result_and_steps(langchain_object, inputs: Union[dict, str], **kwa # to display intermediate steps langchain_object.return_intermediate_steps = True try: - fix_memory_inputs(langchain_object) + if not isinstance(langchain_object, AgentExecutor): + fix_memory_inputs(langchain_object) except Exception as exc: logger.error(f"Error fixing memory inputs: {exc}") From 2725e24ced035aa11b80e932c30fd4fd383c0e2c Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Wed, 9 Aug 2023 21:11:00 -0300 Subject: [PATCH 2/8] =?UTF-8?q?=F0=9F=9A=80=20feat(constants.py):=20add=20?= =?UTF-8?q?BaseMemory=20to=20LANGCHAIN=5FBASE=5FTYPES=20to=20support=20cus?= =?UTF-8?q?tom=20memory=20implementation=20in=20Langchain=20interface?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 📝 WHY: The addition of BaseMemory to LANGCHAIN_BASE_TYPES allows for the customization of the memory component in the Langchain interface. This enables users to implement their own memory functionality according to their specific needs. --- src/backend/langflow/interface/custom/constants.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/backend/langflow/interface/custom/constants.py b/src/backend/langflow/interface/custom/constants.py index 83cf4b463..891fc75f9 100644 --- a/src/backend/langflow/interface/custom/constants.py +++ b/src/backend/langflow/interface/custom/constants.py @@ -8,6 +8,7 @@ from langchain.text_splitter import TextSplitter from langchain.tools import Tool from langchain.vectorstores.base import VectorStore from langchain.schema import BaseOutputParser +from langchain.schema.memory import BaseMemory LANGCHAIN_BASE_TYPES = { @@ -22,6 +23,7 @@ LANGCHAIN_BASE_TYPES = { "Embeddings": Embeddings, "BaseRetriever": BaseRetriever, "BaseOutputParser": BaseOutputParser, + "BaseMemory": BaseMemory, } # Langchain base types plus Python base types From 31e02fe25c4e5a1db66ea45a3f1a12321aff9d60 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Wed, 9 Aug 2023 21:37:11 -0300 Subject: [PATCH 3/8] =?UTF-8?q?=E2=9C=A8=20feat(ConversationalAgent.py):?= =?UTF-8?q?=20add=20ConversationalAgent=20component=20to=20handle=20conver?= =?UTF-8?q?sational=20interactions=20using=20OpenAI's=20function=20calling?= =?UTF-8?q?=20API?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit adds a new file `ConversationalAgent.py` to the `src/backend/langflow/components/agents` directory. The `ConversationalAgent` class is a custom component that represents a conversational agent capable of using OpenAI's function calling API. The `ConversationalAgent` class has the following features: - It inherits from the `CustomComponent` class. - It has a `display_name` attribute set to "OpenaAI Conversational Agent". - It has a `description` attribute set to "Conversational Agent that can use OpenAI's function calling API". - It implements the `build_config` method to define the configuration options for the agent. - It implements the `build` method to create an instance of the `AgentExecutor` class, which represents the agent's execution environment. - The `build` method takes several parameters, including `model_name`, `tools`, `memory`, `system_message`, and `max_token_limit`. - It uses the `ChatOpenAI` class from the `langchain.chat_models` module to create an instance of the OpenAI language model. - It uses the `ConversationTokenBufferMemory` class from the `langchain.memory.token_buffer` module to handle conversation history and token buffering. - It uses the `OpenAIFunctionsAgent` class from the `langchain.agents.openai_functions_agent.base` module to create an instance of the OpenAI functions agent. - It returns an instance of the `AgentExecutor` class with the agent, tools, memory, verbose, and return_intermediate_steps parameters set. 📝 feat(__init__.py): add empty __init__.py file to the agents directory This commit adds an empty `__init__.py` file to the `src/backend/langflow/components/agents` directory. The `__init__.py` file is necessary to make the `agents` directory a Python package. --- .../components/agents/ConversationalAgent.py | 71 +++++++++++++++++++ .../langflow/components/agents/__init__.py | 0 2 files changed, 71 insertions(+) create mode 100644 src/backend/langflow/components/agents/ConversationalAgent.py create mode 100644 src/backend/langflow/components/agents/__init__.py diff --git a/src/backend/langflow/components/agents/ConversationalAgent.py b/src/backend/langflow/components/agents/ConversationalAgent.py new file mode 100644 index 000000000..9c2bb400b --- /dev/null +++ b/src/backend/langflow/components/agents/ConversationalAgent.py @@ -0,0 +1,71 @@ +from langflow import CustomComponent +from typing import Optional +from langchain.prompts import SystemMessagePromptTemplate +from langchain.tools import Tool +from langchain.schema.memory import BaseMemory +from langchain.chat_models import ChatOpenAI + +from langchain.agents.agent import AgentExecutor +from langchain.agents.openai_functions_agent.base import OpenAIFunctionsAgent +from langchain.memory.token_buffer import ConversationTokenBufferMemory +from langchain.prompts.chat import MessagesPlaceholder +from langchain.agents.agent_toolkits.conversational_retrieval.openai_functions import ( + _get_default_system_message, +) + + +class ConversationalAgent(CustomComponent): + display_name: str = "OpenaAI Conversational Agent" + description: str = "Conversational Agent that can use OpenAI's function calling API" + + def build_config(self): + openai_function_models = [ + "gpt-3.5-turbo-0613", + "gpt-3.5-turbo-16k-0613", + "gpt-4-0613", + "gpt-4-32k-0613", + ] + return { + "tools": {"is_list": True}, + "model_name": { + "display_name": "Model Name", + "options": openai_function_models, + "value": openai_function_models[0], + }, + "code": {"show": False}, + } + + def build( + self, + model_name: str, + tools: Tool, + memory: Optional[BaseMemory] = None, + system_message: Optional[SystemMessagePromptTemplate] = None, + max_token_limit: int = 2000, + ) -> AgentExecutor: + llm = ChatOpenAI(model_name=model_name) + if not memory: + memory_key = "chat_history" + memory = ConversationTokenBufferMemory( + memory_key=memory_key, + return_messages=True, + output_key="output", + llm=llm, + max_token_limit=max_token_limit, + ) + else: + memory_key = memory.memory_key + + _system_message = system_message or _get_default_system_message() + prompt = OpenAIFunctionsAgent.create_prompt( + system_message=_system_message, + extra_prompt_messages=[MessagesPlaceholder(variable_name=memory_key)], + ) + agent = OpenAIFunctionsAgent(llm=llm, tools=tools, prompt=prompt) + return AgentExecutor( + agent=agent, + tools=tools, + memory=memory, + verbose=True, + return_intermediate_steps=True, + ) diff --git a/src/backend/langflow/components/agents/__init__.py b/src/backend/langflow/components/agents/__init__.py new file mode 100644 index 000000000..e69de29bb From 44f4fc1e62a7add19bf6ffda6afdb185f119aa3c Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Wed, 9 Aug 2023 21:38:39 -0300 Subject: [PATCH 4/8] =?UTF-8?q?=E2=9C=A8=20feat(OpenAIConversationalAgent.?= =?UTF-8?q?py):=20add=20implementation=20of=20ConversationalAgent=20class?= =?UTF-8?q?=20for=20OpenAI=20conversational=20agent?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../{ConversationalAgent.py => OpenAIConversationalAgent.py} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/backend/langflow/components/agents/{ConversationalAgent.py => OpenAIConversationalAgent.py} (100%) diff --git a/src/backend/langflow/components/agents/ConversationalAgent.py b/src/backend/langflow/components/agents/OpenAIConversationalAgent.py similarity index 100% rename from src/backend/langflow/components/agents/ConversationalAgent.py rename to src/backend/langflow/components/agents/OpenAIConversationalAgent.py From 5d226d43d133df9ed100c5e1d3356f256d51ab3a Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Wed, 9 Aug 2023 21:48:40 -0300 Subject: [PATCH 5/8] =?UTF-8?q?=F0=9F=90=9B=20fix(OpenAIConversationalAgen?= =?UTF-8?q?t.py):=20change=20parameter=20name=20from=20model=5Fname=20to?= =?UTF-8?q?=20model=20to=20improve=20clarity=20and=20consistency?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../langflow/components/agents/OpenAIConversationalAgent.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backend/langflow/components/agents/OpenAIConversationalAgent.py b/src/backend/langflow/components/agents/OpenAIConversationalAgent.py index 9c2bb400b..d3164e9a3 100644 --- a/src/backend/langflow/components/agents/OpenAIConversationalAgent.py +++ b/src/backend/langflow/components/agents/OpenAIConversationalAgent.py @@ -43,7 +43,7 @@ class ConversationalAgent(CustomComponent): system_message: Optional[SystemMessagePromptTemplate] = None, max_token_limit: int = 2000, ) -> AgentExecutor: - llm = ChatOpenAI(model_name=model_name) + llm = ChatOpenAI(model=model_name) if not memory: memory_key = "chat_history" memory = ConversationTokenBufferMemory( From 1dcdc02e4f43d24af19fc4788e96b43d6baaf816 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Wed, 9 Aug 2023 21:49:20 -0300 Subject: [PATCH 6/8] =?UTF-8?q?=F0=9F=9A=80=20feat(constants.py):=20import?= =?UTF-8?q?=20BaseChatMemory=20from=20langchain.memory.chat=5Fmemory=20mod?= =?UTF-8?q?ule=20to=20add=20support=20for=20chat=20memory=20in=20custom=20?= =?UTF-8?q?interfaces?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/backend/langflow/interface/custom/constants.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/backend/langflow/interface/custom/constants.py b/src/backend/langflow/interface/custom/constants.py index 891fc75f9..89d187bb8 100644 --- a/src/backend/langflow/interface/custom/constants.py +++ b/src/backend/langflow/interface/custom/constants.py @@ -9,7 +9,7 @@ from langchain.tools import Tool from langchain.vectorstores.base import VectorStore from langchain.schema import BaseOutputParser from langchain.schema.memory import BaseMemory - +from langchain.memory.chat_memory import BaseChatMemory LANGCHAIN_BASE_TYPES = { "Chain": Chain, @@ -24,6 +24,7 @@ LANGCHAIN_BASE_TYPES = { "BaseRetriever": BaseRetriever, "BaseOutputParser": BaseOutputParser, "BaseMemory": BaseMemory, + "BaseChatMemory": BaseChatMemory, } # Langchain base types plus Python base types From 33ef3b0a7e1a9bdb90019726e71d1c61c5dae338 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Wed, 9 Aug 2023 21:58:25 -0300 Subject: [PATCH 7/8] =?UTF-8?q?=F0=9F=90=9B=20fix(OpenAIConversationalAgen?= =?UTF-8?q?t.py):=20ignore=20type=20errors=20for=20memory=5Fkey,=20system?= =?UTF-8?q?=5Fmessage,=20prompt,=20agent,=20and=20tools=20variables=20?= =?UTF-8?q?=E2=9C=A8=20feat(OpenAIConversationalAgent.py):=20add=20support?= =?UTF-8?q?=20for=20return=5Fintermediate=5Fsteps=20parameter=20in=20Agent?= =?UTF-8?q?Executor=20constructor=20to=20enable=20returning=20intermediate?= =?UTF-8?q?=20steps=20during=20conversation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/agents/OpenAIConversationalAgent.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/backend/langflow/components/agents/OpenAIConversationalAgent.py b/src/backend/langflow/components/agents/OpenAIConversationalAgent.py index d3164e9a3..06c0d6779 100644 --- a/src/backend/langflow/components/agents/OpenAIConversationalAgent.py +++ b/src/backend/langflow/components/agents/OpenAIConversationalAgent.py @@ -54,17 +54,19 @@ class ConversationalAgent(CustomComponent): max_token_limit=max_token_limit, ) else: - memory_key = memory.memory_key + memory_key = memory.memory_key # type: ignore _system_message = system_message or _get_default_system_message() prompt = OpenAIFunctionsAgent.create_prompt( - system_message=_system_message, + system_message=_system_message, # type: ignore extra_prompt_messages=[MessagesPlaceholder(variable_name=memory_key)], ) - agent = OpenAIFunctionsAgent(llm=llm, tools=tools, prompt=prompt) + agent = OpenAIFunctionsAgent( + llm=llm, tools=tools, prompt=prompt # type: ignore + ) return AgentExecutor( agent=agent, - tools=tools, + tools=tools, # type: ignore memory=memory, verbose=True, return_intermediate_steps=True, From b0a2258232cbbdce9fd4f682575ccc056acf1ca0 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Wed, 9 Aug 2023 22:06:33 -0300 Subject: [PATCH 8/8] =?UTF-8?q?=F0=9F=94=A7=20chore(OpenAIConversationalAg?= =?UTF-8?q?ent.py):=20add=20display=20names=20for=20'tools',=20'memory',?= =?UTF-8?q?=20'system=5Fmessage',=20and=20'max=5Ftoken=5Flimit'=20paramete?= =?UTF-8?q?rs=20to=20improve=20readability=20and=20user=20experience?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../langflow/components/agents/OpenAIConversationalAgent.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/backend/langflow/components/agents/OpenAIConversationalAgent.py b/src/backend/langflow/components/agents/OpenAIConversationalAgent.py index 06c0d6779..5d089ab3b 100644 --- a/src/backend/langflow/components/agents/OpenAIConversationalAgent.py +++ b/src/backend/langflow/components/agents/OpenAIConversationalAgent.py @@ -26,7 +26,10 @@ class ConversationalAgent(CustomComponent): "gpt-4-32k-0613", ] return { - "tools": {"is_list": True}, + "tools": {"is_list": True, "display_name": "Tools"}, + "memory": {"display_name": "Memory"}, + "system_message": {"display_name": "System Message"}, + "max_token_limit": {"display_name": "Max Token Limit"}, "model_name": { "display_name": "Model Name", "options": openai_function_models,