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:
@@ -9,6 +9,7 @@ System prompts are static constants to enable Anthropic prompt caching.
|
|||||||
"""
|
"""
|
||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
|
import re
|
||||||
import uuid
|
import uuid
|
||||||
from typing import Any
|
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."""
|
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:
|
def _get_client() -> anthropic.AsyncAnthropic:
|
||||||
"""Get configured async Anthropic client."""
|
"""Get configured async Anthropic client."""
|
||||||
if not settings.ANTHROPIC_API_KEY:
|
if not settings.ANTHROPIC_API_KEY:
|
||||||
@@ -141,7 +151,7 @@ async def scaffold_branches(
|
|||||||
messages=[{"role": "user", "content": user_message}],
|
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
|
input_tokens = response.usage.input_tokens
|
||||||
output_tokens = response.usage.output_tokens
|
output_tokens = response.usage.output_tokens
|
||||||
cost = _estimate_cost(input_tokens, output_tokens)
|
cost = _estimate_cost(input_tokens, output_tokens)
|
||||||
@@ -197,7 +207,7 @@ async def generate_branch_detail(
|
|||||||
messages=messages,
|
messages=messages,
|
||||||
)
|
)
|
||||||
|
|
||||||
raw_text = response.content[0].text
|
raw_text = _strip_markdown_fences(response.content[0].text)
|
||||||
total_input += response.usage.input_tokens
|
total_input += response.usage.input_tokens
|
||||||
total_output += response.usage.output_tokens
|
total_output += response.usage.output_tokens
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user