From ae4f0bda76441e8c285000b2c1da67920736d610 Mon Sep 17 00:00:00 2001 From: FlorentLvr Date: Fri, 20 Dec 2024 07:25:34 +0100 Subject: [PATCH] fix: get agent tools dynamically --- lib/abi/services/agent/Agent.py | 38 +++++++- src/assistants/foundation/SupervisorAgent.py | 92 +++++++++----------- 2 files changed, 78 insertions(+), 52 deletions(-) diff --git a/lib/abi/services/agent/Agent.py b/lib/abi/services/agent/Agent.py index 435870a9..5fbff631 100644 --- a/lib/abi/services/agent/Agent.py +++ b/lib/abi/services/agent/Agent.py @@ -381,4 +381,40 @@ class AgentToolSchema(BaseModel): description=self.__description, func=self.__tool_function, args_schema=AgentToolSchema - )] \ No newline at end of file + )] + + @property + def tools(self) -> list[Tool]: + """Get the list of tools available to the agent. + + Returns: + list[Tool]: List of tools configured for this agent + """ + return self.__tools + + @property + def name(self) -> str: + """Get the name of the agent. + + Returns: + str: The agent's name + """ + return self.__name + + @property + def description(self) -> str: + """Get the description of the agent. + + Returns: + str: The agent's description + """ + return self.__description + + @property + def chat_model(self) -> BaseChatModel: + """Get the chat model used by the agent. + + Returns: + BaseChatModel: The agent's chat model + """ + return self.__chat_model \ No newline at end of file diff --git a/src/assistants/foundation/SupervisorAgent.py b/src/assistants/foundation/SupervisorAgent.py index 4ebf279b..7dc6b901 100644 --- a/src/assistants/foundation/SupervisorAgent.py +++ b/src/assistants/foundation/SupervisorAgent.py @@ -2,9 +2,11 @@ from abi.services.agent.Agent import Agent, AgentConfiguration, AgentSharedState, MemorySaver from src import secret from src.apps.terminal_agent.terminal_style import print_tool_usage, print_tool_response +from abi import logger SUPERVISOR_AGENT_INSTRUCTIONS = """ You are ABI a super-assistant. +Present yourself as a super-assistant and by listing all the assistants you have access to. Chain of thought: 1. Identify if user intent can be solved with one of the assistants (tools) already created. If so, use the right assistant to answer the user's question. @@ -16,41 +18,7 @@ For assistants tools, make sure to validate input arguments mandatory fields (not optional) with the user in human readable terms according to the provided schema before proceeding. You have access to the following assistants: -- OpenData Assistant: Use for open data analysis -Integrations: -- Perplexity: useful to access the web - -- Content Assistant: Use for content analysis and optimization -Workflows: -- LinkedinPostsWorkflow: Use to get LinkedIn posts from a profile or organization -Integrations: -- Replicate: useful to generate images and videos - -- Growth Assistant: Use for growth and marketing analysis. -Workflows: -- LinkedinPostsInteractionsWorkflow: Use to extract people (firstname, lastname, occupation, profile_url) or organization who interacted with a LinkedIn post. -Integrations: -- Linkedin: useful to get insights from LinkedIn posts, profiles and organizations. -- HubSpot: useful to manage contacts, deals and companies - -- Sales Assistant: Use for sales and marketing analysis -Workflows: -- CreateContactWorkflow: useful to create a new contact in HubSpot -Integrations: -- HubSpot: useful to manage contacts, deals and companies - -- Operations Assistant: Use for operations and marketing analysis -Workflows: -- GetTopPrioritiesWorkflow: useful to get the top priorities from ontology store -- CreateIssueAndAddToProjectWorkflow: useful to create a new issue in GitHub and add it to a project -- AssignIssuesToProjectWorkflow: useful to assign all issue from repository to a project -- GithubIssuesPipeline: useful to map github issues to ontology -- AddAssistantsToNaasWorkspaceWorkflow: useful to add assistants to Naas workspace - -Integrations: -- Aia: useful to generate AIA in a given workspace from a linkedin_url profile -- Naas: useful to manage Naas workspace, plugins and ontologies -- Finance Assistant: Use for financial analysis and insights, can access Stripe integration. +{{ASSISTANTS}} - Support Assistant: Use to get any feedbacks/bugs or needs from user. Chain of thought: @@ -67,7 +35,6 @@ def create_supervisor_agent(): agent_configuration = AgentConfiguration( on_tool_usage=lambda message: print_tool_usage(message.tool_calls[0]['name']), on_tool_response=lambda message: print_tool_response(f'\n{message.content}'), - system_prompt=SUPERVISOR_AGENT_INSTRUCTIONS ) model = ChatOpenAI(model="gpt-4o", temperature=0, api_key=secret.get('OPENAI_API_KEY')) @@ -80,22 +47,45 @@ def create_supervisor_agent(): from src.assistants.domain.FinanceAssistant import create_finance_assistant from src.assistants.foundation.SupportAssitant import create_support_assistant - open_data_assistant = create_open_data_assistant(AgentSharedState(thread_id=1), agent_configuration) - content_assistant = create_content_assistant(AgentSharedState(thread_id=2), agent_configuration) - growth_assistant = create_growth_assistant(AgentSharedState(thread_id=3), agent_configuration) - sales_assistant = create_sales_assistant(AgentSharedState(thread_id=4), agent_configuration) - operations_assistant = create_operations_assistant(AgentSharedState(thread_id=5), agent_configuration) - finance_assistant = create_finance_assistant(AgentSharedState(thread_id=6), agent_configuration) - support_assistant = create_support_assistant(AgentSharedState(thread_id=7), agent_configuration) + # Create assistant instances + assistants = [ + create_open_data_assistant(AgentSharedState(thread_id=1), agent_configuration), + create_content_assistant(AgentSharedState(thread_id=2), agent_configuration), + create_growth_assistant(AgentSharedState(thread_id=3), agent_configuration), + create_sales_assistant(AgentSharedState(thread_id=4), agent_configuration), + create_operations_assistant(AgentSharedState(thread_id=5), agent_configuration), + create_finance_assistant(AgentSharedState(thread_id=6), agent_configuration), + create_support_assistant(AgentSharedState(thread_id=7), agent_configuration) + ] + + # Collect all tools from assistants + tools = [] + for assistant in assistants: + tools.extend(assistant.as_tools()) + + # Get tools info from each assistant + assistants_info = [] + for assistant in assistants[:-1]: # Exclude support assistant + assistant_info = { + "name": assistant.name, + "description": assistant.description, + "tools": [ + {"name": t.name, "description": t.description} + for t in assistant.tools # Access the private tools attribute + ] + } + assistants_info.append(assistant_info) + + # Transform assistants_info into formatted string + assistants_info_str = "" + for assistant in assistants_info: + assistants_info_str += f"-{assistant['name']}: {assistant['description']}\n" + for tool in assistant['tools']: + assistants_info_str += f" • {tool['name']}: {tool['description']}\n" + assistants_info_str += "\n" - tools = [] + \ - open_data_assistant.as_tools() + \ - content_assistant.as_tools() + \ - growth_assistant.as_tools() + \ - sales_assistant.as_tools() + \ - operations_assistant.as_tools() + \ - finance_assistant.as_tools() + \ - support_assistant.as_tools() + # Replace the {{ASSISTANTS}} placeholder in the system prompt with the assistants_info + agent_configuration.system_prompt=SUPERVISOR_AGENT_INSTRUCTIONS.replace("{{ASSISTANTS}}", assistants_info_str) return Agent( name="supervisor_agent",