diff --git a/app/plugins/builtins/ai_proactive/jobs.py b/app/plugins/builtins/ai_proactive/jobs.py index 53fc99e..9e38988 100644 --- a/app/plugins/builtins/ai_proactive/jobs.py +++ b/app/plugins/builtins/ai_proactive/jobs.py @@ -225,6 +225,12 @@ async def deep_analysis( content = response.choices[0].message.content if not content: 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) if not suggestion_data.get("title") or not suggestion_data.get("content"): return diff --git a/app/plugins/builtins/ai_proactive/services.py b/app/plugins/builtins/ai_proactive/services.py index b1c3f2e..b56c4cf 100644 --- a/app/plugins/builtins/ai_proactive/services.py +++ b/app/plugins/builtins/ai_proactive/services.py @@ -435,6 +435,12 @@ async def generate_suggestion( content = response.choices[0].message.content if not content: 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) # Validate required fields if not result.get("title") or not result.get("content"): diff --git a/app/plugins/builtins/unified_search/query_understanding.py b/app/plugins/builtins/unified_search/query_understanding.py index ac7d2e8..9971835 100644 --- a/app/plugins/builtins/unified_search/query_understanding.py +++ b/app/plugins/builtins/unified_search/query_understanding.py @@ -104,6 +104,12 @@ async def llm_analyze_query( response = await litellm.acompletion(**litellm_kwargs) 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) except Exception: 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) 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) except Exception: logger.warning("LLM result aggregation failed, using fallback", exc_info=True)