Download src/agents/output_parsers/functions.py from InvestmentResearchAI/LLM-ADE-dev: direct link, hf CLI and curl.
- Browser
- Download file 2.82 kB
-
https://huggingface.co/spaces/InvestmentResearchAI/LLM-ADE-dev/resolve/main/src/agents/output_parsers/functions.py
- Command line
-
hf download hf://spaces/InvestmentResearchAI/LLM-ADE-dev/src/agents/output_parsers/functions.py
-
curl -L -o functions.py https://huggingface.co/spaces/InvestmentResearchAI/LLM-ADE-dev/resolve/main/src/agents/output_parsers/functions.py
2.82 kB
| import re | |
| from json import JSONDecodeError | |
| from typing import List, Union | |
| from langchain_core.agents import AgentAction, AgentActionMessageLog, AgentFinish | |
| from langchain_core.exceptions import OutputParserException | |
| from langchain_core.messages import ( | |
| AIMessage, | |
| BaseMessage, | |
| ) | |
| from langchain_core.outputs import ChatGeneration, Generation | |
| from langchain.agents.agent import AgentOutputParser | |
| from agents.output_parsers.utils import parse_tool_call, check_tool_call | |
| import ast | |
| class FunctionsAgentOutputParser(AgentOutputParser): | |
| """Parses a message into agent action/finish. | |
| Is meant to be used with a model with Nous Hermes 2 Pro as the base, as it relies on the specific | |
| function_call parameter from Nous Research to convey what tools to use. | |
| If a function_call parameter is passed, then that is used to get | |
| the tool and tool input. | |
| If one is not passed, then the AIMessage is assumed to be the final output. | |
| It was add a | |
| """ | |
| def _type(self) -> str: | |
| return "functions-agent" | |
| def _parse_ai_message(message: BaseMessage): | |
| """Parse an AI message.""" | |
| if not isinstance(message, AIMessage): | |
| raise TypeError(f"Expected an AI message got {type(message)}") | |
| actions = [] | |
| pattern = re.compile(r"<tool_call>(.*?)</tool_call>", re.DOTALL) | |
| try: | |
| tool_calls = [parse_tool_call(t.strip()) for t in pattern.findall(message.content)] | |
| except: | |
| raise OutputParserException( | |
| f"Could not parse tool calls from message content: {message.content}. Please ensure that the tool calls are valid JSON." | |
| ) | |
| if not tool_calls: | |
| return AgentFinish( | |
| return_values={"output": message.content}, log=str(message.content) | |
| ) | |
| for tool_call in tool_calls: | |
| tool_name, tool_input = check_tool_call(tool_call) | |
| content_msg = f"\n{message.content}\n" if message.content else "\n" | |
| log = f"\nInvoking: `{tool_name}` with `{tool_input}`\n{content_msg}\n" | |
| actions.append(AgentActionMessageLog( | |
| tool=tool_name, | |
| tool_input=tool_input, | |
| log=log, | |
| message_log=[message], | |
| )) | |
| return actions | |
| def parse_result( | |
| self, result: List[Generation], *, partial: bool = False | |
| ) -> Union[AgentAction, AgentFinish]: | |
| if not isinstance(result[0], ChatGeneration): | |
| raise ValueError("This output parser only works on ChatGeneration output") | |
| message = result[0].message | |
| return self._parse_ai_message(message) | |
| def parse(self, text: str) -> Union[AgentAction, AgentFinish]: | |
| raise ValueError("Can only parse messages") |