diff --git a/metagpt/utils/repair_llm_raw_output.py b/metagpt/utils/repair_llm_raw_output.py index 06484f71d..b8756e8c6 100644 --- a/metagpt/utils/repair_llm_raw_output.py +++ b/metagpt/utils/repair_llm_raw_output.py @@ -119,6 +119,7 @@ def repair_json_format(output: str) -> str: logger.info(f"repair_json_format: {'}]'}") elif output.startswith("{") and output.endswith("]"): output = output[:-1] + "}" + # remove comments in output json string, after json value content, maybe start with #, maybe start with // arr = output.split("\n") new_arr = [] @@ -208,6 +209,17 @@ def repair_invalid_json(output: str, error: str) -> str: elif (rline[col_no] in ["'", '"']) and (line.startswith('"') or line.startswith("'")) and "," not in line: # problem, `"""` or `'''` without `,` new_line = f",{line}" + elif col_no - 1 >= 0 and rline[col_no - 1] in ['"', "'"]: + # backslash problem like \" in the output + char = rline[col_no - 1] + nearest_char_idx = rline[col_no:].find(char) + new_line = ( + rline[: col_no - 1] + + "\\" + + rline[col_no - 1 : col_no + nearest_char_idx] + + "\\" + + rline[col_no + nearest_char_idx :] + ) elif '",' not in line and "," not in line and '"' not in line: new_line = f'{line}",' elif not line.endswith(","): diff --git a/tests/metagpt/utils/test_repair_llm_raw_output.py b/tests/metagpt/utils/test_repair_llm_raw_output.py index e28423b91..7a29ea3ee 100644 --- a/tests/metagpt/utils/test_repair_llm_raw_output.py +++ b/tests/metagpt/utils/test_repair_llm_raw_output.py @@ -211,6 +211,11 @@ value output = repair_invalid_json(output, "Expecting ',' delimiter: line 4 column 1") assert output == target_output + raw_output = '{"key": "url "http" \\"https\\" "}' + target_output = '{"key": "url \\"http\\" \\"https\\" "}' + output = repair_invalid_json(raw_output, "Expecting ',' delimiter: line 1 column 15 (char 14)") + assert output == target_output + def test_retry_parse_json_text(): from metagpt.utils.repair_llm_raw_output import retry_parse_json_text