fix: strip markdown code fences from LLM responses before json.loads

- glm-5.2 returns JSON wrapped in ```json ... ``` code fences
- Added fence stripping in services.py, query_understanding.py, jobs.py
This commit is contained in:
Agent Zero
2026-07-19 02:30:07 +02:00
parent 6ed0752536
commit 5c3fc027bc
3 changed files with 24 additions and 0 deletions
@@ -225,6 +225,12 @@ async def deep_analysis(
content = response.choices[0].message.content content = response.choices[0].message.content
if not content: if not content:
return return
# Strip markdown code fences if present
content = content.strip()
if content.startswith("```"):
content = content.split("\n", 1)[-1] if "\n" in content else content[3:]
if content.endswith("```"):
content = content[:-3].strip()
suggestion_data = json.loads(content) suggestion_data = json.loads(content)
if not suggestion_data.get("title") or not suggestion_data.get("content"): if not suggestion_data.get("title") or not suggestion_data.get("content"):
return return
@@ -435,6 +435,12 @@ async def generate_suggestion(
content = response.choices[0].message.content content = response.choices[0].message.content
if not content: if not content:
return None return None
# Strip markdown code fences if present (e.g. ```json ... ```)
content = content.strip()
if content.startswith("```"):
content = content.split("\n", 1)[-1] if "\n" in content else content[3:]
if content.endswith("```"):
content = content[:-3].strip()
result = json.loads(content) result = json.loads(content)
# Validate required fields # Validate required fields
if not result.get("title") or not result.get("content"): if not result.get("title") or not result.get("content"):
@@ -104,6 +104,12 @@ async def llm_analyze_query(
response = await litellm.acompletion(**litellm_kwargs) response = await litellm.acompletion(**litellm_kwargs)
content = response.choices[0].message.content content = response.choices[0].message.content
# Strip markdown code fences if present
content = content.strip()
if content.startswith("```"):
content = content.split("\n", 1)[-1] if "\n" in content else content[3:]
if content.endswith("```"):
content = content[:-3].strip()
return json.loads(content) return json.loads(content)
except Exception: except Exception:
logger.warning("LLM query analysis failed, using fallback", exc_info=True) logger.warning("LLM query analysis failed, using fallback", exc_info=True)
@@ -150,6 +156,12 @@ async def llm_aggregate_results(
response = await litellm.acompletion(**litellm_kwargs) response = await litellm.acompletion(**litellm_kwargs)
content = response.choices[0].message.content content = response.choices[0].message.content
# Strip markdown code fences if present
content = content.strip()
if content.startswith("```"):
content = content.split("\n", 1)[-1] if "\n" in content else content[3:]
if content.endswith("```"):
content = content[:-3].strip()
return json.loads(content) return json.loads(content)
except Exception: except Exception:
logger.warning("LLM result aggregation failed, using fallback", exc_info=True) logger.warning("LLM result aggregation failed, using fallback", exc_info=True)