fix(openclaw): robust JSON repair for small LLM responses
All checks were successful
E2E Health Check / e2e-health (push) Successful in 19s

This commit is contained in:
OG T
2026-03-31 15:04:39 +08:00
parent 27a0cd0af4
commit 3562a67a58

View File

@@ -942,31 +942,61 @@ class OpenClawService:
# =========================================================================
def _extract_json_from_response(self, text: str) -> str | None:
"""從 LLM 回應中提取 JSON"""
# 嘗試直接解析
"""從 LLM 回應中提取 JSON (含啟發式修補)"""
# 0. 清理開頭結尾空白
text = text.strip()
if not text:
return None
# 1. 嘗試直接解析
try:
json.loads(text)
return text
except json.JSONDecodeError:
pass
# 嘗試從 markdown code block 提取
# 2. 嘗試從 markdown code block 提取
patterns = [
r"```json\s*([\s\S]*?)\s*```",
r"```\s*([\s\S]*?)\s*```",
r"\{[\s\S]*\}",
r"(\{[\s\S]*\})", # 貪婪匹配最大括號對
]
for pattern in patterns:
match = re.search(pattern, text)
if match:
candidate = match.group(1) if "```" in pattern else match.group(0)
candidate = match.group(1) if "(" in pattern else match.group(0)
candidate = candidate.strip()
try:
json.loads(candidate)
return candidate
except json.JSONDecodeError:
# 3. 啟發式修補: 如果結尾缺少括號,嘗試補齊
if candidate.startswith("{") and not candidate.endswith("}"):
for i in range(1, 5): # 嘗試補 1-5 個括號/引號
try:
repaired = candidate + '"' * (i-1) + "}" * i
json.loads(repaired)
logger.info("json_repaired_heuristically", level=i)
return repaired
except:
continue
continue
# 4. 極端情況: 找出最後一個有效 key
if "{" in text:
start_idx = text.find("{")
candidate = text[start_idx:]
# 暴力去除非法尾綴 (如 \t\t...)
candidate = re.sub(r"[ \t\r\n]+$", "", candidate)
if not candidate.endswith("}"):
candidate += '"}' # 嘗試最簡單的閉合
try:
json.loads(candidate)
return candidate
except:
pass
return None
def _parse_analysis_result(self, raw_response: str) -> OpenClawDecision | None: