From ef6c4b0abd1375ebd79afd3e78c6cb123c28839b Mon Sep 17 00:00:00 2001 From: ogt Date: Thu, 25 Jun 2026 14:52:31 +0800 Subject: [PATCH] fix: hide model timeout in deploy review reports --- config.py | 2 +- docs/AI_INTELLIGENCE_MODULE_SOT.md | 1 + services/code_review_pipeline_service.py | 27 ++++++++++++++++++------ tests/test_code_review_claude_routing.py | 4 +++- 4 files changed, 26 insertions(+), 8 deletions(-) diff --git a/config.py b/config.py index cd7e520..fbbfe7f 100644 --- a/config.py +++ b/config.py @@ -402,7 +402,7 @@ YOUTUBE_API_KEY = os.getenv('YOUTUBE_API_KEY', '') # ========================================== # 系統版本與路徑 # ========================================== -SYSTEM_VERSION = "V10.678" +SYSTEM_VERSION = "V10.679" LOG_FILE_PATH = os.path.join(BASE_DIR, 'logs/system.log') public_url = PUBLIC_URL # 用於模板顯示 diff --git a/docs/AI_INTELLIGENCE_MODULE_SOT.md b/docs/AI_INTELLIGENCE_MODULE_SOT.md index 2983203..0c7d65f 100644 --- a/docs/AI_INTELLIGENCE_MODULE_SOT.md +++ b/docs/AI_INTELLIGENCE_MODULE_SOT.md @@ -755,3 +755,4 @@ POSTGRES_HOST=momo-db | 2026-06-25 | 觀測台入口與通知預覽不可用工程主語干擾營運判讀 | V10.676 起觀測台導覽統一使用「AI 分工矩陣」,通知模板列表會把 K8s/Pod/資料庫/CI Pipeline 等內部詞轉成服務健康、資料連線與部署流程;主機健康事件與自癒劇本改顯示任務/問題/處置提醒,不直接露 `unknown_task`、`scheduler_task_failure`、`CODE_FIX` 等 raw code。 | | 2026-06-25 | 部署監控不得用退役正式域名判定失敗 | V10.677 起 CI/CD 狀態 API 與 active blackbox 監控預設以 `PUBLIC_URL` / `PROD_BASE_URL` 對齊現行正式入口 `https://mo.wooo.work/health`,不再把 `momo.wooo.work` timeout 判成正式部署失敗;Webcrumbs loader fallback 也改為資訊級降級訊號,避免健康頁與 log 產生假紅燈。 | | 2026-06-25 | 匯入任務公開摘要不得回傳資料表或本機檔案定位 | V10.678 起 `/api/import_jobs` / `/api/import_job/` 的 `import_summary` 只回傳營運摘要、日期範圍、匯入筆數與同步狀態,不再外露 `table_name`、`synced_to`、`daily_sales_snapshot`、`realtime_sales_monthly`、Google Drive file id 或本機暫存路徑。 | +| 2026-06-25 | 部署後 Code Review 不得把模型 timeout 寫成部署錯誤 | V10.679 起本地掃描可收斂的 Code Review 報告不再顯示「最後錯誤 / all hosts failed / OpenClaw timeout」等模型內部訊息;歷史 API 讀舊紀錄時也即時轉為「AI 延伸分析暫時略過,已以本地掃描完成部署後檢查」。 | diff --git a/services/code_review_pipeline_service.py b/services/code_review_pipeline_service.py index 8508cef..19092ac 100644 --- a/services/code_review_pipeline_service.py +++ b/services/code_review_pipeline_service.py @@ -116,6 +116,7 @@ ALLOW_INSECURE_WEBHOOK = os.getenv("MOMO_ALLOW_INSECURE_INTERNAL_WEBHOOK_FOR_DEV AIDER_AUTO_FIX_FILE_PATTERN = re.compile( r"^(services|routes|database)/(?:[a-zA-Z0-9_]+/)*[a-zA-Z0-9_]+\.py$" ) +_OPENCLAW_RAW_ERROR_RE = re.compile(r"[;;]?\s*最後錯誤:[^<\n\r]+") # Phase 7 Frontier 升級 feature flag — 預設 OFF;啟用後只作 Ollama 失敗後的雲端備援。 CODE_REVIEW_USE_CLAUDE = os.getenv("CODE_REVIEW_USE_CLAUDE", "false").lower() == "true" @@ -127,6 +128,18 @@ def _aider_allowed_fix_files(files: List[str]) -> List[str]: return [f for f in files if AIDER_AUTO_FIX_FILE_PATTERN.match(f or "")] +def _public_openclaw_report(report: Any) -> str: + """Hide model timeout internals from post-deploy reports shown to operators.""" + text = str(report or "") + if not text: + return "" + text = _OPENCLAW_RAW_ERROR_RE.sub(";AI 延伸分析暫時略過,已以本地掃描完成部署後檢查", text) + text = text.replace("本地降級報告", "本地掃描報告") + text = text.replace("deterministic scan", "本地掃描") + text = text.replace("OpenClaw", "AI 架構檢查") + return text + + def _code_review_ollama_host_reachable(host: str) -> bool: """Short-circuit dead GCP Ollama hosts before a generate timeout.""" if not CODE_REVIEW_OLLAMA_HOST_PREFLIGHT_ENABLED: @@ -816,15 +829,14 @@ class CodeReviewPipeline: top = [f for f in findings[:2] if f.get("description")] top_text = ";".join( f"{f.get('file', 'unknown')}:{f.get('description')}" for f in top - ) or "本次 deterministic scan 未發現高風險問題" - error_text = (last_error or "local Ollama unavailable")[:120] + ) or "本次本地掃描未發現高風險問題" return ( f"🔍 整體風險等級 {risk}。" f"本地掃描完成 {len(files)} 檔,CRITICAL={sev['critical']}、HIGH={sev['high']}、" f"MEDIUM={sev['medium']}、LOW={sev['low']}。" f"⚠️ 最需關注問題 {top_text}。" - f"💡 架構優化方向 GCP-A/GCP-B OpenClaw 不可用時暫停 111 重分析,避免拖高 fallback 主機負載。" - f"✅ 本次部署亮點 已以本地降級報告收斂,未呼叫 Gemini;最後錯誤:{error_text}" + f"💡 架構優化方向 AI 架構檢查延伸分析不可用時,以本地掃描收斂,避免拖高模型主機負載。" + f"✅ 本次部署亮點 已以本地掃描報告收斂,未呼叫 Gemini;AI 延伸分析暫時略過。" ) # ── Step 4:ElephantAlpha 決策 ───────────────────────────────────────────── @@ -1169,7 +1181,10 @@ def trigger_post_deploy_review( def get_current_state() -> Dict[str, Any]: """前端 polling 用:取得目前 pipeline 即時狀態""" with _pipeline_lock: - return dict(_current_pipeline) + state = dict(_current_pipeline) + if state.get("openclaw_report"): + state["openclaw_report"] = _public_openclaw_report(state.get("openclaw_report")) + return state def get_history(limit: int = 20) -> List[Dict]: @@ -1203,7 +1218,7 @@ def get_history(limit: int = 20) -> List[Dict]: "total_issues": sum(sev.values()), "auto_fix": meta.get("auto_fix_triggered", False), "findings": content.get("findings", []), - "openclaw_report": content.get("openclaw_report", ""), + "openclaw_report": _public_openclaw_report(content.get("openclaw_report", "")), "ea_decision": content.get("ea_decision", {}), "created_at": r[4].isoformat() if r[4] else "", "status": r[5] or "active", diff --git a/tests/test_code_review_claude_routing.py b/tests/test_code_review_claude_routing.py index 3e7bb65..a615927 100644 --- a/tests/test_code_review_claude_routing.py +++ b/tests/test_code_review_claude_routing.py @@ -487,7 +487,9 @@ def test_openclaw_skips_111_and_cloud_by_default_when_gcp_pair_fails(monkeypatch findings=[], ) - assert "本地降級報告" in result + assert "本地掃描報告" in result + assert "最後錯誤" not in result + assert "all hosts failed" not in result assert [call["model"] for call in calls] == ["qwen2.5-coder:7b", "gemma3:4b"] assert not any("192.168.0.111" in call["host"] for call in calls) fake_claude.generate.assert_not_called()