From d294caf830640c417bf1b5530fef1779119a9b31 Mon Sep 17 00:00:00 2001 From: OG T Date: Thu, 16 Apr 2026 14:34:50 +0800 Subject: [PATCH] =?UTF-8?q?fix(solver):=20=E7=9B=B8=E5=AE=B9=20openclaw=5F?= =?UTF-8?q?nemo=20=E5=9B=9E=E5=82=B3=E6=A0=BC=E5=BC=8F=20=E2=86=92=20candi?= =?UTF-8?q?dates=20=E6=A0=BC=E5=BC=8F=E8=BD=89=E6=8F=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 與 diagnostician 同步:openclaw_nemo 回傳 action_title/risk_level/confidence, solver 的 _extract_candidates() 找不到 candidates key → 空方案 → no_candidates 修復: 檢測 action_title 存在時轉換為 candidates 格式 risk_level → blast_radius 映射: critical=60, high=40, medium=25, low=10 Co-Authored-By: Claude Sonnet 4.6 --- apps/api/src/agents/solver_agent.py | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/apps/api/src/agents/solver_agent.py b/apps/api/src/agents/solver_agent.py index d62f6dcb..3ab91848 100644 --- a/apps/api/src/agents/solver_agent.py +++ b/apps/api/src/agents/solver_agent.py @@ -200,7 +200,31 @@ blast_radius 參考: # ───────────────────────────────────────────────────────────────────────────── def _extract_candidates(parsed: dict[str, Any]) -> list[CandidateAction]: - """從 LLM 解析結果提取候選方案(按信心降序)。""" + """從 LLM 解析結果提取候選方案(按信心降序)。 + + 支援兩種格式: + 1. 標準格式:{"candidates": [{action, blast_radius, rollback_cost, confidence, rationale}]} + 2. OpenClaw Nemo 格式:{"action_title": "...", "risk_level": "...", "confidence": 0.85} + + 2026-04-16 ogt + Claude Sonnet 4.6: 與 diagnostician 同步,修復 openclaw_nemo 格式不相容 + """ + # OpenClaw Nemo 格式轉換 + if "action_title" in parsed and "candidates" not in parsed: + action_title = str(parsed.get("action_title", "")) + confidence = float(parsed.get("confidence", 0.5)) + risk_level = str(parsed.get("risk_level", "medium")) + risk_to_blast = {"critical": 60, "high": 40, "medium": 25, "low": 10} + blast = risk_to_blast.get(risk_level.lower(), 30) + if action_title and confidence > 0: + return [CandidateAction( + action=action_title[:200], + blast_radius=blast, + rollback_cost=20, + confidence=confidence, + rationale=f"OpenClaw Nemo 建議: {action_title}", + )] + return [] + raw = parsed.get("candidates", []) candidates = [] for item in raw: