diff --git a/src/promptflow-tools/promptflow/tools/common.py b/src/promptflow-tools/promptflow/tools/common.py index f957f55f6f6..1737c114328 100644 --- a/src/promptflow-tools/promptflow/tools/common.py +++ b/src/promptflow-tools/promptflow/tools/common.py @@ -222,7 +222,7 @@ def validate_tools(tools): def try_parse_name_and_content(role_prompt): # customer can add ## in front of name/content for markdown highlight. # and we still support name/content without ## prefix for backward compatibility. - pattern = r"\n*#{0,2}\s*name:\n+\s*(\S+)\s*\n*#{0,2}\s*content:\n?(.*)" + pattern = r"\n*#{0,2}\s*name\s*:\s*\n+\s*(\S+)\s*\n*#{0,2}\s*content\s*:\s*\n?(.*)" match = re.search(pattern, role_prompt, re.DOTALL) if match: return match.group(1), match.group(2) @@ -232,7 +232,7 @@ def try_parse_name_and_content(role_prompt): def try_parse_tool_call_id_and_content(role_prompt): # customer can add ## in front of tool_call_id/content for markdown highlight. # and we still support tool_call_id/content without ## prefix for backward compatibility. - pattern = r"\n*#{0,2}\s*tool_call_id:\n+\s*(\S+)\s*\n*#{0,2}\s*content:\n?(.*)" + pattern = r"\n*#{0,2}\s*tool_call_id\s*:\s*\n+\s*(\S+)\s*\n*#{0,2}\s*content\s*:\s*\n?(.*)" match = re.search(pattern, role_prompt, re.DOTALL) if match: return match.group(1), match.group(2) diff --git a/src/promptflow-tools/tests/test_common.py b/src/promptflow-tools/tests/test_common.py index 78f30790b0c..97373babdaa 100644 --- a/src/promptflow-tools/tests/test_common.py +++ b/src/promptflow-tools/tests/test_common.py @@ -214,7 +214,10 @@ def test_success_parse_role_prompt(self, chat_str, images, image_detail, expecte ("\nsystem:\nname:\n\n content:\nfirst", [ {'role': 'system', 'content': 'name:\n\n content:\nfirst'}]), ("\nsystem:\nname:\n\n", [ - {'role': 'system', 'content': 'name:'}]) + {'role': 'system', 'content': 'name:'}]), + # portal may add extra \r to new line character. + ("function:\r\nname:\r\n AI\ncontent :\r\nfirst", [ + {'role': 'function', 'name': 'AI', 'content': 'first'}]), ], ) def test_parse_chat_with_name_in_role_prompt(self, chat_str, expected_result): @@ -240,6 +243,20 @@ def test_try_parse_chat_with_tools(self, example_prompt_template_with_tool, pars actual_result = parse_chat(example_prompt_template_with_tool) assert actual_result == parsed_chat_with_tools + @pytest.mark.parametrize( + "chat_str, expected_result", + [ + ("\n#tool:\n## tool_call_id:\nid \n content:\nfirst\n\n#user:\nsecond", [ + {'role': 'tool', 'tool_call_id': 'id', 'content': 'first'}, {'role': 'user', 'content': 'second'}]), + # portal may add extra \r to new line character. + ("\ntool:\ntool_call_id :\r\nid\n content:\r\n", [ + {'role': 'tool', 'tool_call_id': 'id', 'content': ''}]), + ], + ) + def test_parse_tool_call_id_and_content(self, chat_str, expected_result): + actual_result = parse_chat(chat_str) + assert actual_result == expected_result + @pytest.mark.parametrize("chunk, error_msg, success", [ (""" ## tool_calls: @@ -275,6 +292,14 @@ def test_try_parse_chat_with_tools(self, example_prompt_template_with_tool, pars "function": {"name": "func1", "arguments": ""} }] """, "", True), + # portal may add extra \r to new line character. + (""" + ## tool_calls:\r + [{ + "id": "tool_call_id", "type": "function", + "function": {"name": "func1", "arguments": ""} + }] + """, "", True), ]) def test_parse_tool_calls_for_assistant(self, chunk: str, error_msg: str, success: bool): last_message = {'role': 'assistant'}