response_parser.py 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. import ast
  2. from opendevin.controller.action_parser import ActionParser, ResponseParser
  3. from opendevin.core.logger import opendevin_logger as logger
  4. from opendevin.events.action import (
  5. Action,
  6. BrowseInteractiveAction,
  7. )
  8. class BrowsingResponseParser(ResponseParser):
  9. def __init__(self):
  10. # Need to pay attention to the item order in self.action_parsers
  11. super().__init__()
  12. self.action_parsers = [BrowsingActionParserMessage()]
  13. self.default_parser = BrowsingActionParserBrowseInteractive()
  14. def parse(self, response: str) -> Action:
  15. action_str = self.parse_response(response)
  16. return self.parse_action(action_str)
  17. def parse_response(self, response) -> str:
  18. action_str = response['choices'][0]['message']['content']
  19. if action_str is None:
  20. return ''
  21. action_str = action_str.strip()
  22. if not action_str.endswith('```'):
  23. action_str = action_str + ')```'
  24. logger.info(action_str)
  25. return action_str
  26. def parse_action(self, action_str: str) -> Action:
  27. for action_parser in self.action_parsers:
  28. if action_parser.check_condition(action_str):
  29. return action_parser.parse(action_str)
  30. return self.default_parser.parse(action_str)
  31. class BrowsingActionParserMessage(ActionParser):
  32. """
  33. Parser action:
  34. - BrowseInteractiveAction(browser_actions) - unexpected response format, message back to user
  35. """
  36. def __init__(
  37. self,
  38. ):
  39. pass
  40. def check_condition(self, action_str: str) -> bool:
  41. return '```' not in action_str
  42. def parse(self, action_str: str) -> Action:
  43. msg = f'send_msg_to_user("""{action_str}""")'
  44. return BrowseInteractiveAction(
  45. browser_actions=msg,
  46. thought=action_str,
  47. browsergym_send_msg_to_user=action_str,
  48. )
  49. class BrowsingActionParserBrowseInteractive(ActionParser):
  50. """
  51. Parser action:
  52. - BrowseInteractiveAction(browser_actions) - handle send message to user function call in BrowserGym
  53. """
  54. def __init__(
  55. self,
  56. ):
  57. pass
  58. def check_condition(self, action_str: str) -> bool:
  59. return True
  60. def parse(self, action_str: str) -> Action:
  61. thought = action_str.split('```')[0].strip()
  62. action_str = action_str.split('```')[1].strip()
  63. msg_content = ''
  64. for sub_action in action_str.split('\n'):
  65. if 'send_msg_to_user(' in sub_action:
  66. tree = ast.parse(sub_action)
  67. args = tree.body[0].value.args # type: ignore
  68. msg_content = args[0].value
  69. return BrowseInteractiveAction(
  70. browser_actions=action_str,
  71. thought=thought,
  72. browsergym_send_msg_to_user=msg_content,
  73. )