diff --git a/src/llm/providers/reasoning.py b/src/llm/providers/reasoning.py index 752132292..4a45c1fc1 100644 --- a/src/llm/providers/reasoning.py +++ b/src/llm/providers/reasoning.py @@ -55,14 +55,17 @@ def _is_json_document(content: str) -> bool: Reasoning followed by a closing tag is never valid JSON, so a structured answer that carries the tag inside a string value is left whole. Input - nested too deeply to parse is not treated as JSON rather than failing the - request. + nested too deeply for the parser to finish is kept whole as well: reasoning + does not open with that many brackets, so cutting it would only risk + truncating a real answer. """ stripped = content.strip() if not stripped.startswith(("{", "[")): return False try: json.loads(stripped) - except (ValueError, RecursionError): + except RecursionError: + return True + except ValueError: return False return True diff --git a/tests/test_reasoning.py b/tests/test_reasoning.py index 3cbee1ef7..c8d923c17 100644 --- a/tests/test_reasoning.py +++ b/tests/test_reasoning.py @@ -70,7 +70,7 @@ def test_strip_reasoning_prefilled_survives_deeply_nested_json() -> None: # Deep enough for json.loads to raise RecursionError on every supported Python. depth = 100_000 content = "[" * depth + '""' + "]" * depth - assert strip_reasoning(content, prefilled=True) == '"' + "]" * depth + assert strip_reasoning(content, prefilled=True) == content def _openai_provider(content: str, **kwargs: Any) -> OpenAIProvider: