From fe77e6d297932b123cfd5812134de05cfc37ce69 Mon Sep 17 00:00:00 2001 From: OG T Date: Fri, 17 Apr 2026 21:36:28 +0800 Subject: [PATCH] =?UTF-8?q?fix(ai):=20SuggestedAction=20enum=20=E6=93=B4?= =?UTF-8?q?=E5=85=85=20+=20Pydantic=20fallback=20=E9=98=B2=E8=AD=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 根本原因: NemoTron 輸出 "investigate" → Pydantic 只接受 4 個值 → 爆炸 → openclaw_analysis_parse_failed → analysis_result=None → 全部 fallback 卡片顯示「待分析」 修復: 1. SuggestedAction enum 新增 INVESTIGATE/OBSERVE/APPLY_HPA/TUNE_RESOURCES (prompt.py 列了 6 個,enum 只有 4 個,prompt/model 不同步是根源) 2. normalize_suggested_action validator: uppercase + 別名映射 + 未知值 fallback NO_ACTION 確保任何 LLM 輸出都不會讓 Pydantic 爆炸導致 analysis_result = None Co-Authored-By: Claude Sonnet 4.6 --- apps/api/src/models/ai.py | 37 ++++++++++++++++++++++++++++++++++--- 1 file changed, 34 insertions(+), 3 deletions(-) diff --git a/apps/api/src/models/ai.py b/apps/api/src/models/ai.py index 9986ec1c..37e867df 100644 --- a/apps/api/src/models/ai.py +++ b/apps/api/src/models/ai.py @@ -19,11 +19,19 @@ class SuggestedAction(str, Enum): AI 建議操作類型 必須與 executor.OperationType 對應 + + 2026-04-17 ogt + Claude Sonnet 4.6: 新增 INVESTIGATE/APPLY_HPA/TUNE_RESOURCES + 根本原因: prompts.py 列了 6 個值,但 enum 只有 4 個 + → NemoTron 輸出 "investigate" → Pydantic 爆炸 → analysis_result = None → 全部 fallback """ RESTART_DEPLOYMENT = "RESTART_DEPLOYMENT" DELETE_POD = "DELETE_POD" SCALE_DEPLOYMENT = "SCALE_DEPLOYMENT" - NO_ACTION = "NO_ACTION" # 無需處理 + APPLY_HPA = "APPLY_HPA" + TUNE_RESOURCES = "TUNE_RESOURCES" + INVESTIGATE = "INVESTIGATE" # 調查診斷,不下執行指令 + OBSERVE = "OBSERVE" # 觀察等待 + NO_ACTION = "NO_ACTION" # 無需處理 class AIRiskLevel(str, Enum): @@ -86,6 +94,7 @@ class OpenClawDecision(BaseModel): ..., description="建議執行的操作類型", ) + target_resource: str = Field( ..., description="目標資源名稱 (e.g., 'harbor', 'grafana')", @@ -192,9 +201,31 @@ class OpenClawDecision(BaseModel): @field_validator("suggested_action", mode="before") @classmethod def normalize_suggested_action(cls, v): - """正規化 suggested_action""" + """ + 正規化 suggested_action:大小寫 + 別名映射 + 未知值 fallback + + 2026-04-17 ogt + Claude Sonnet 4.6(亞太): + 根本原因: NemoTron 輸出 "investigate"(小寫) → Pydantic 拒絕 → analysis_result = None + 舊版只做 uppercase,未知值仍爆 → 修復為: 先 uppercase,再別名映射,最後 fallback NO_ACTION + """ if isinstance(v, str): - return v.upper().replace("-", "_").replace(" ", "_") + normalized = v.upper().replace("-", "_").replace(" ", "_") + # 別名映射 (LLM 可能輸出非正式名稱) + alias_map = { + "DIAGNOSE": "INVESTIGATE", + "DEBUG": "INVESTIGATE", + "MONITOR": "OBSERVE", + "WATCH": "OBSERVE", + "TUNE": "TUNE_RESOURCES", + "HPA": "APPLY_HPA", + } + normalized = alias_map.get(normalized, normalized) + # 未知值 fallback NO_ACTION,絕不讓 Pydantic 爆炸導致 analysis_result = None + try: + SuggestedAction(normalized) + return normalized + except ValueError: + return "NO_ACTION" return v