Spaces:
Paused
Paused
| import re | |
| from typing import Union | |
| from langchain.agents.agent import AgentOutputParser | |
| from langchain.agents.mrkl.output_parser import MRKLOutputParser | |
| #from langchain.agents.mrkl.prompt import FORMAT_INSTRUCTIONS | |
| from langchain.schema import AgentAction, AgentFinish, OutputParserException | |
| FORMAT_INSTRUCTIONS0 = """Use the following format and be sure to use new lines after each task. | |
| Question: the input question you must answer | |
| Thought: you should always think about what to do | |
| Action: Exactly only one word out of: {tool_names} | |
| Action Input: the input to the action | |
| Observation: the result of the action | |
| (this Thought/Action/Action Input/Observation can repeat N times) | |
| Thought: I now know the final answer | |
| Final Answer: the final answer to the original input question""" | |
| FORMAT_INSTRUCTIONS = """List of tools, use exactly one word when choosing Action: {tool_names} | |
| Here is an example sequence to follow: | |
| Question: What is the latest news? | |
| Thought: I should search online for the latest news. | |
| Action: Search | |
| Action Input: What is the latest news? | |
| Observation: X is going away. Z is again happening. | |
| Thought: That is interesting, I should search for more information about X and Z and also search about Q. | |
| Action: Search | |
| Action Input: How is X impacting things. Why is Z happening again, and what are the consequences? | |
| Observation: X is causing Y. Z may be caused by P and will lead to H. | |
| Thought: I now know the final answer | |
| Final Answer: The latest news is: | |
| * X is going away, and this is caused by Y. | |
| * Z is happening again, and the cause is P and will lead to H. | |
| Overall, X and Z are important problems. | |
| """ | |
| FINAL_ANSWER_ACTION = "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 H2OMRKLOutputParser(MRKLOutputParser): | |
| """MRKL Output parser for the chat agent.""" | |
| def get_format_instructions(self) -> str: | |
| return FORMAT_INSTRUCTIONS | |
| def parse(self, text: str) -> Union[AgentAction, AgentFinish]: | |
| includes_answer = FINAL_ANSWER_ACTION in 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 includes_answer: | |
| return AgentFinish( | |
| {"output": text.split(FINAL_ANSWER_ACTION)[-1].strip()}, text | |
| ) | |
| elif action_match: | |
| action = action_match.group(1).strip() | |
| action_input = action_match.group(2) | |
| tool_input = action_input.strip(" ") | |
| # ensure if its a well formed SQL query we don't remove any trailing " chars | |
| if tool_input.startswith("SELECT ") is False: | |
| 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 "mrkl" | |