diff --git a/langchain/agents/agent_toolkits/openapi/planner.py b/langchain/agents/agent_toolkits/openapi/planner.py index b9ae8d52..bf4e1280 100644 --- a/langchain/agents/agent_toolkits/openapi/planner.py +++ b/langchain/agents/agent_toolkits/openapi/planner.py @@ -24,6 +24,7 @@ from langchain.agents.mrkl.base import ZeroShotAgent from langchain.agents.tools import Tool from langchain.chains.llm import LLMChain from langchain.llms.openai import OpenAI +from langchain.memory import ReadOnlySharedMemory from langchain.prompts import PromptTemplate from langchain.requests import RequestsWrapper from langchain.schema import BaseLanguageModel @@ -53,7 +54,8 @@ class RequestsGetToolWithParsing(BaseRequestsTool, BaseTool): data = json.loads(text) except json.JSONDecodeError as e: raise e - response = self.requests_wrapper.get(data["url"]) + data_params = data.get("params") + response = self.requests_wrapper.get(data["url"], params=data_params) response = response[: self.response_length] return self.llm_chain.predict( response=response, instructions=data["output_instructions"] @@ -183,6 +185,7 @@ def create_openapi_agent( api_spec: ReducedOpenAPISpec, requests_wrapper: RequestsWrapper, llm: BaseLanguageModel, + shared_memory: Optional[ReadOnlySharedMemory] = None, ) -> AgentExecutor: """Instantiate API planner and controller for a given spec. @@ -207,7 +210,7 @@ def create_openapi_agent( }, ) agent = ZeroShotAgent( - llm_chain=LLMChain(llm=llm, prompt=prompt), + llm_chain=LLMChain(llm=llm, prompt=prompt, memory=shared_memory), allowed_tools=[tool.name for tool in tools], ) return AgentExecutor.from_agent_and_tools(agent=agent, tools=tools, verbose=True) diff --git a/langchain/agents/agent_toolkits/openapi/planner_prompt.py b/langchain/agents/agent_toolkits/openapi/planner_prompt.py index 9940a791..4db0fd8d 100644 --- a/langchain/agents/agent_toolkits/openapi/planner_prompt.py +++ b/langchain/agents/agent_toolkits/openapi/planner_prompt.py @@ -40,7 +40,7 @@ Here are endpoints you can use. Do not reference any of the endpoints above. User query: {query} Plan:""" API_PLANNER_TOOL_NAME = "api_planner" -API_PLANNER_TOOL_DESCRIPTION = f"Can be used to generate the right API calls to assist with a user query, like {API_PLANNER_TOOL_NAME}(query). Should always be called before trying to calling the API controller." +API_PLANNER_TOOL_DESCRIPTION = f"Can be used to generate the right API calls to assist with a user query, like {API_PLANNER_TOOL_NAME}(query). Should always be called before trying to call the API controller." # Execution. API_CONTROLLER_PROMPT = """You are an agent that gets a sequence of API calls and given their documentation, should execute them and return the final response. @@ -81,7 +81,7 @@ API_CONTROLLER_TOOL_DESCRIPTION = f"Can be used to execute a plan of API calls, # The goal is to have an agent at the top-level (e.g. so it can recover from errors and re-plan) while # keeping planning (and specifically the planning prompt) simple. API_ORCHESTRATOR_PROMPT = """You are an agent that assists with user queries against API, things like querying information or creating resources. -Some user queries can be resolved in a single API call though some require several API call. +Some user queries can be resolved in a single API call, particularly if you can find appropriate params from the OpenAPI spec; though some require several API call. You should always plan your API calls first, and then execute the plan second. You should never return information without executing the api_controller tool. @@ -106,12 +106,12 @@ User query: can you add some trendy stuff to my shopping cart. Thought: I should plan API calls first. Action: api_planner Action Input: I need to find the right API calls to add trendy items to the users shopping cart -Observation: 1) GET /items/trending to get trending item ids +Observation: 1) GET /items with params 'trending' is 'True' to get trending item ids 2) GET /user to get user 3) POST /cart to post the trending items to the user's cart Thought: I'm ready to execute the API calls. Action: api_controller -Action Input: 1) GET /items/trending to get trending item ids +Action Input: 1) GET /items params 'trending' is 'True' to get trending item ids 2) GET /user to get user 3) POST /cart to post the trending items to the user's cart ... @@ -123,8 +123,12 @@ Thought: I should generate a plan to help with this query and then copy that pla {agent_scratchpad}""" REQUESTS_GET_TOOL_DESCRIPTION = """Use this to GET content from a website. -Input to the tool should be a json string with 2 keys: "url" and "output_instructions". -The value of "url" should be a string. The value of "output_instructions" should be instructions on what information to extract from the response, for example the id(s) for a resource(s) that the GET request fetches. +Input to the tool should be a json string with 3 keys: "url", "params" and "output_instructions". +The value of "url" should be a string. +The value of "params" should be a dict of the needed and available parameters from the OpenAPI spec related to the endpoint. +If parameters are not needed, or not available, leave it empty. +The value of "output_instructions" should be instructions on what information to extract from the response, +for example the id(s) for a resource(s) that the GET request fetches. """ PARSING_GET_PROMPT = PromptTemplate(