Spaces:
Runtime error
Runtime error
| import re | |
| from typing import Union | |
| from langchain_core.agents import AgentAction, AgentFinish | |
| from langchain_core.exceptions import OutputParserException | |
| from langchain.agents.agent import AgentOutputParser | |
| from langchain.agents.mrkl.prompt import FORMAT_INSTRUCTIONS | |
| FINAL_ANSWER_ACTIONS = ["Final Answer:**", "Final Answer:", "Final Answer**:", "Final Answer"] | |
| MISSING_ACTION_AFTER_THOUGHT_ERROR_MESSAGE = "Invalid Format: Missing 'Action:' after 'Thought:" | |
| MISSING_ACTION_INPUT_AFTER_ACTION_ERROR_MESSAGE = "Invalid Format: Missing 'Action Input:' after 'Action:'" | |
| FINAL_ANSWER_AND_PARSABLE_ACTION_ERROR_MESSAGE = "Parsing LLM output produced both a final answer and a parse-able action:" | |
| class ReActSingleInputOutputParser(AgentOutputParser): | |
| """Parses ReAct-style LLM calls that have a single tool input. | |
| Expects output to be in one of two formats. | |
| If the output signals that an action should be taken, | |
| should be in the below format. This will result in an AgentAction | |
| being returned. | |
| ``` | |
| Thought: agent thought here | |
| Action: search | |
| Action Input: what is the temperature in SF? | |
| ``` | |
| If the output signals that a final answer should be given, | |
| should be in the below format. This will result in an AgentFinish | |
| being returned. | |
| ``` | |
| Thought: agent thought here | |
| Final Answer: The temperature is 100 degrees | |
| ``` | |
| """ | |
| def get_format_instructions(self) -> str: | |
| return FORMAT_INSTRUCTIONS | |
| def parse(self, text: str) -> Union[AgentAction, AgentFinish]: | |
| for final_answer_action in FINAL_ANSWER_ACTIONS: | |
| includes_answer = final_answer_action in text | |
| if includes_answer: | |
| return AgentFinish({"output": text.split(final_answer_action)[-1].strip()}, text) | |
| regex = r"Action\s*\d*\s*:[\s]*(.*?)[\s]*Action\s*\d*\s*Input\s*\d*\s*:[\s]*(.*)" | |
| action_match = re.search(regex, text, re.DOTALL) | |
| if action_match: | |
| action = action_match.group(1).strip() | |
| action_input = action_match.group(2) | |
| tool_input = action_input.strip(" ") | |
| tool_input = tool_input.strip('"') | |
| return AgentAction(action, tool_input, text) | |
| if not re.search(r"Action\s*\d*\s*:[\s]*(.*?)", text, re.DOTALL): | |
| raise OutputParserException( | |
| f"Could not parse LLM output: `{text}`", | |
| observation=MISSING_ACTION_AFTER_THOUGHT_ERROR_MESSAGE, | |
| llm_output=text, | |
| send_to_llm=True, | |
| ) | |
| elif not re.search(r"[\s]*Action\s*\d*\s*Input\s*\d*\s*:[\s]*(.*)", text, re.DOTALL): | |
| raise OutputParserException( | |
| f"Could not parse LLM output: `{text}`", | |
| observation=MISSING_ACTION_INPUT_AFTER_ACTION_ERROR_MESSAGE, | |
| llm_output=text, | |
| send_to_llm=True, | |
| ) | |
| else: | |
| raise OutputParserException(f"Could not parse LLM output: `{text}`") | |
| def _type(self) -> str: | |
| return "react-single-input" | |