From 9451e1b694898e6133fe7e8d57ab3d612c1670dc Mon Sep 17 00:00:00 2001 From: majiayu000 <1835304752@qq.com> Date: Wed, 24 Dec 2025 11:52:13 +0800 Subject: [PATCH] fix: clean tags from model output in parse_action Add explicit removal of and tags from model output before parsing. This uses replace() instead of slice indexing to handle cases where the model output format may vary. The model sometimes outputs responses wrapped in tags, which was causing action parsing to fail or produce malformed output. Fixes #258 --- phone_agent/actions/handler.py | 6 +++ tests/test_answer_tag_cleaning.py | 61 +++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+) create mode 100644 tests/test_answer_tag_cleaning.py diff --git a/phone_agent/actions/handler.py b/phone_agent/actions/handler.py index 0bef1c3a..5bb2d965 100644 --- a/phone_agent/actions/handler.py +++ b/phone_agent/actions/handler.py @@ -345,6 +345,12 @@ def parse_action(response: str) -> dict[str, Any]: print(f"Parsing action: {response}") try: response = response.strip() + + # Clean up tags that may be in model output + response = response.replace('', '') + response = response.replace('', '') + response = response.strip() + if response.startswith('do(action="Type"') or response.startswith( 'do(action="Type_Name"' ): diff --git a/tests/test_answer_tag_cleaning.py b/tests/test_answer_tag_cleaning.py new file mode 100644 index 00000000..abdf7996 --- /dev/null +++ b/tests/test_answer_tag_cleaning.py @@ -0,0 +1,61 @@ +"""Tests for answer tag cleaning in handler.py. + +This test verifies that parse_action properly cleans and +tags from model output (Issue #258). +""" + +import os +import re +import unittest + + +class TestAnswerTagCleaning(unittest.TestCase): + """Test that handler.py cleans answer tags from model output.""" + + def test_handler_cleans_answer_tags(self): + """Verify handler.py removes and tags.""" + handler_py_path = os.path.join( + os.path.dirname(os.path.dirname(__file__)), + 'phone_agent', 'actions', 'handler.py' + ) + + with open(handler_py_path, 'r', encoding='utf-8') as f: + content = f.read() + + # Check for answer tag cleaning in parse_action function + self.assertIn("replace('', '')", content, + "handler.py should remove tags") + self.assertIn("replace('', '')", content, + "handler.py should remove tags") + + def test_answer_tag_cleaning_uses_replace(self): + """Verify answer tag cleaning uses replace() instead of slice indexing.""" + handler_py_path = os.path.join( + os.path.dirname(os.path.dirname(__file__)), + 'phone_agent', 'actions', 'handler.py' + ) + + with open(handler_py_path, 'r', encoding='utf-8') as f: + content = f.read() + + # Find parse_action function content + parse_action_start = content.find('def parse_action') + self.assertNotEqual(parse_action_start, -1, + "Could not find parse_action function") + + # Get function body (until next def or end of file) + next_def = content.find('\ndef ', parse_action_start + 1) + if next_def == -1: + parse_action_body = content[parse_action_start:] + else: + parse_action_body = content[parse_action_start:next_def] + + # Verify both tags are cleaned using replace + self.assertIn(".replace('', '')", parse_action_body, + "Should use replace() for tag cleaning") + self.assertIn(".replace('', '')", parse_action_body, + "Should use replace() for tag cleaning") + + +if __name__ == '__main__': + unittest.main()