diff --git a/src/readme2demo/llm.py b/src/readme2demo/llm.py index fb0d7bf..d6e644c 100644 --- a/src/readme2demo/llm.py +++ b/src/readme2demo/llm.py @@ -463,7 +463,7 @@ def complete(system: str, user: str, model: str, max_tokens: int = 8192) -> LLMR def extract_json(text: str) -> str: """Pull the first JSON object out of a response (handles ```json fences).""" - fence = re.search(r"```(?:json)?\s*\n(.*?)```", text, re.DOTALL) + fence = re.search(r"```(?:json)?\s*(.*?)\s*```", text, re.DOTALL) if fence: return fence.group(1).strip() start = text.find("{") diff --git a/tests/test_llm_backend.py b/tests/test_llm_backend.py index 250b379..94c8148 100644 --- a/tests/test_llm_backend.py +++ b/tests/test_llm_backend.py @@ -321,6 +321,12 @@ def test_anthropic_default_model_matches_config(): assert llm.PROVIDERS["anthropic"].default_model == Config().model +def test_extract_json_accepts_single_line_fenced_json(): + text = 'diagnostic {not json} ```json {"ok": true}```' + + assert llm.extract_json(text) == '{"ok": true}' + + # -- openai backend -----------------------------------------------------------------