diff --git a/python/packages/orchestrations/agent_framework_orchestrations/_magentic.py b/python/packages/orchestrations/agent_framework_orchestrations/_magentic.py index 6206022f043..2ef67a922cc 100644 --- a/python/packages/orchestrations/agent_framework_orchestrations/_magentic.py +++ b/python/packages/orchestrations/agent_framework_orchestrations/_magentic.py @@ -427,8 +427,20 @@ def _extract_json(text: str) -> dict[str, Any]: raise ValueError("No JSON object found.") depth = 0 end = None + in_string = False + escaped = False for i, ch in enumerate(text[start:], start=start): - if ch == "{": + # Braces inside string values, such as code in an instruction, do not count. + if in_string: + if escaped: + escaped = False + elif ch == "\\": + escaped = True + elif ch == '"': + in_string = False + elif ch == '"': + in_string = True + elif ch == "{": depth += 1 elif ch == "}": depth -= 1 diff --git a/python/packages/orchestrations/tests/test_magentic.py b/python/packages/orchestrations/tests/test_magentic.py index 38a3dcc718c..5890c834e0d 100644 --- a/python/packages/orchestrations/tests/test_magentic.py +++ b/python/packages/orchestrations/tests/test_magentic.py @@ -1456,4 +1456,18 @@ def test_extract_json_reads_first_fenced_object(text: str) -> None: assert _extract_json(text)["is_request_satisfied"] is True +@pytest.mark.parametrize( + "text", + [ + '{"is_request_satisfied": true, "answer": "The f-string is missing its closing } so add it."}', + 'Ledger: {"is_request_satisfied": true, "answer": "Open the block with { and keep going"} done', + '{"is_request_satisfied": true, "answer": "Escaped quote \\" then a brace }"}', + ], +) +def test_extract_json_ignores_braces_inside_strings(text: str) -> None: + from agent_framework_orchestrations._magentic import _extract_json # type: ignore + + assert _extract_json(text)["is_request_satisfied"] is True + + # endregion