diff --git a/backend/app/core/ai_tree_generator_service.py b/backend/app/core/ai_tree_generator_service.py index 805c84f7..34af11d2 100644 --- a/backend/app/core/ai_tree_generator_service.py +++ b/backend/app/core/ai_tree_generator_service.py @@ -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