Преглед изворни кода

(Browsing agent) Fix send_msg_to_user (#4354)

Engel Nyst пре 1 година
родитељ
комит
20455cea3e

+ 21 - 5
openhands/agenthub/browsing_agent/response_parser.py

@@ -1,4 +1,5 @@
 import ast
 import ast
+import re
 
 
 from openhands.controller.action_parser import ActionParser, ResponseParser
 from openhands.controller.action_parser import ActionParser, ResponseParser
 from openhands.core.logger import openhands_logger as logger
 from openhands.core.logger import openhands_logger as logger
@@ -24,8 +25,13 @@ class BrowsingResponseParser(ResponseParser):
         if action_str is None:
         if action_str is None:
             return ''
             return ''
         action_str = action_str.strip()
         action_str = action_str.strip()
-        if action_str and not action_str.endswith('```'):
-            action_str = action_str + ')```'
+        # Ensure action_str ends with ')```'
+        if action_str:
+            if not action_str.endswith('```'):
+                if action_str.endswith(')'):
+                    action_str += '```'  # prevent duplicate ending paranthesis, e.g. send_msg_to_user('Done'))
+                else:
+                    action_str += ')```'  # expected format
         logger.debug(action_str)
         logger.debug(action_str)
         return action_str
         return action_str
 
 
@@ -96,9 +102,19 @@ class BrowsingActionParserBrowseInteractive(ActionParser):
         msg_content = ''
         msg_content = ''
         for sub_action in browser_actions.split('\n'):
         for sub_action in browser_actions.split('\n'):
             if 'send_msg_to_user(' in sub_action:
             if 'send_msg_to_user(' in sub_action:
-                tree = ast.parse(sub_action)
-                args = tree.body[0].value.args  # type: ignore
-                msg_content = args[0].value
+                try:
+                    tree = ast.parse(sub_action)
+                    args = tree.body[0].value.args  # type: ignore
+                    msg_content = args[0].value
+                except SyntaxError:
+                    logger.error(f'Error parsing action: {sub_action}')
+                    # the syntax was not correct, but we can still try to get the message
+                    # e.g. send_msg_to_user("Hello, world!") or send_msg_to_user('Hello, world!'
+                    match = re.search(r'send_msg_to_user\((["\'])(.*?)\1\)', sub_action)
+                    if match:
+                        msg_content = match.group(2)
+                    else:
+                        msg_content = ''
 
 
         return BrowseInteractiveAction(
         return BrowseInteractiveAction(
             browser_actions=browser_actions,
             browser_actions=browser_actions,

+ 30 - 2
tests/unit/test_browsing_agent_parser.py

@@ -12,10 +12,14 @@ from openhands.agenthub.browsing_agent.response_parser import (
         ("click('81'", "click('81')```"),
         ("click('81'", "click('81')```"),
         (
         (
             '"We need to search the internet\n```goto("google.com")',
             '"We need to search the internet\n```goto("google.com")',
-            '"We need to search the internet\n```goto("google.com"))```',
+            '"We need to search the internet\n```goto("google.com")```',
         ),
         ),
         ("```click('81'", "```click('81')```"),
         ("```click('81'", "```click('81')```"),
-        ("click('81')", "click('81'))```"),
+        ("click('81')", "click('81')```"),
+        (
+            "send_msg_to_user('The server might not be running or accessible. Please check the server status and try again.')",
+            "send_msg_to_user('The server might not be running or accessible. Please check the server status and try again.')```",
+        ),
     ],
     ],
 )
 )
 def test_parse_response(action_str: str, expected: str) -> None:
 def test_parse_response(action_str: str, expected: str) -> None:
@@ -37,6 +41,30 @@ def test_parse_response(action_str: str, expected: str) -> None:
             'We need to perform a click',
             'We need to perform a click',
             '',
             '',
         ),
         ),
+        (
+            'Tell the user that the city was built in 1751.\n```send_msg_to_user("Based on the results of my search, the city was built in 1751.")',
+            'send_msg_to_user("Based on the results of my search, the city was built in 1751.")',
+            'Tell the user that the city was built in 1751.',
+            'Based on the results of my search, the city was built in 1751.',
+        ),
+        (
+            'Tell the user that the city was built in 1751.\n```send_msg_to_user("Based on the results of my search, the city was built in 1751.")```',
+            'send_msg_to_user("Based on the results of my search, the city was built in 1751.")',
+            'Tell the user that the city was built in 1751.',
+            'Based on the results of my search, the city was built in 1751.',
+        ),
+        (
+            "Tell the user that the city was built in 1751.\n```send_msg_to_user('Based on the results of my search, the city was built in 1751.')```",
+            "send_msg_to_user('Based on the results of my search, the city was built in 1751.')",
+            'Tell the user that the city was built in 1751.',
+            'Based on the results of my search, the city was built in 1751.',
+        ),
+        (
+            "send_msg_to_user('The server might not be running or accessible. Please check the server status and try again.'))```",
+            "send_msg_to_user('The server might not be running or accessible. Please check the server status and try again.'))",
+            '',
+            'The server might not be running or accessible. Please check the server status and try again.',
+        ),
     ],
     ],
 )
 )
 def test_parse_action(
 def test_parse_action(