Coverage for mindsdb / interfaces / agents / safe_output_parser.py: 50%
28 statements
« prev ^ index » next coverage.py v7.13.1, created at 2026-01-21 00:36 +0000
« prev ^ index » next coverage.py v7.13.1, created at 2026-01-21 00:36 +0000
1import re
2from typing import Union
4from langchain_core.agents import AgentAction, AgentFinish
6from langchain.agents.agent import AgentOutputParser
7from langchain.agents.conversational.prompt import FORMAT_INSTRUCTIONS
9from mindsdb.utilities import log
11logger = log.getLogger(__name__)
14class SafeOutputParser(AgentOutputParser):
15 '''Output parser for the conversational agent that does not throw OutputParserException.'''
17 ai_prefix: str = 'AI'
18 '''Prefix to use before AI output.'''
20 format_instructions: str = FORMAT_INSTRUCTIONS
21 '''Default formatting instructions'''
23 def get_format_instructions(self) -> str:
24 '''Returns formatting instructions for the given output parser.'''
25 return self.format_instructions
27 def parse(self, text: str) -> Union[AgentAction, AgentFinish]:
28 '''Parses outputted text from an LLM.
30 Args:
31 text (str): Outputted text to parse.
33 Returns:
34 output (str): Parsed text to an Agent step.
35 '''
36 regex = r'Action: (.*?)[\n]*Action Input:([\s\S]*)'
37 match = re.search(regex, text, re.DOTALL)
38 if match is not None:
39 action = match.group(1)
40 action_input = match.group(2)
41 return AgentAction(action.strip(), action_input.strip(' ').strip('"'), text)
42 output = text
43 if f'{self.ai_prefix}:' in text:
44 output = text.split(f'{self.ai_prefix}:')[-1].strip()
45 return AgentFinish(
46 {'output': output}, text
47 )
49 @property
50 def _type(self) -> str:
51 return 'conversational'