fix: strip markdown code fences from AI JSON responses

Haiku sometimes wraps its JSON in ```json ... ``` despite the prompt
instructing otherwise. Strip fences before parsing to avoid JSONDecodeError
at char 0.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
chihlasm
2026-02-21 03:55:21 -05:00
parent 25df9421f9
commit 950f6750e0

View File

@@ -9,6 +9,7 @@ System prompts are static constants to enable Anthropic prompt caching.
"""
import json
import logging
import re
import uuid
from typing import Any
@@ -94,6 +95,15 @@ Return a corrected full JSON object only. No markdown, no prose, no code fences.
Fix ALL listed errors while maintaining the same troubleshooting/procedural logic."""
def _strip_markdown_fences(text: str) -> str:
"""Strip markdown code fences if the model wrapped its JSON response."""
text = text.strip()
match = re.match(r"^```(?:json)?\s*([\s\S]*?)```$", text)
if match:
return match.group(1).strip()
return text
def _get_client() -> anthropic.AsyncAnthropic:
"""Get configured async Anthropic client."""
if not settings.ANTHROPIC_API_KEY:
@@ -141,7 +151,7 @@ async def scaffold_branches(
messages=[{"role": "user", "content": user_message}],
)
raw_text = response.content[0].text
raw_text = _strip_markdown_fences(response.content[0].text)
input_tokens = response.usage.input_tokens
output_tokens = response.usage.output_tokens
cost = _estimate_cost(input_tokens, output_tokens)
@@ -197,7 +207,7 @@ async def generate_branch_detail(
messages=messages,
)
raw_text = response.content[0].text
raw_text = _strip_markdown_fences(response.content[0].text)
total_input += response.usage.input_tokens
total_output += response.usage.output_tokens