feat(phase32): 實作 review_push + gitea_webhook 改用本地 Ollama 審查
Some checks failed
CD Pipeline / build-and-deploy (push) Has been cancelled

- local_code_review_service: 新增 review_push() 方法
  使用 qwen2.5-coder:7b 審查 push event(非 PR)
- gitea_webhook_service: _call_openclaw_push_review 改用本地推理
  OpenClaw 無 push-review 端點(404) → 改用 LocalCodeReviewService

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
OG T
2026-04-10 11:09:11 +08:00
parent b24fae313e
commit ab6f6faa32
2 changed files with 64 additions and 15 deletions

View File

@@ -180,6 +180,49 @@ class LocalCodeReviewService:
except Exception as e:
logger.warning("pr_review_db_save_failed", error=str(e))
async def review_push(
self,
repo_name: str,
branch: str,
commit_summary: str,
files_summary: str,
) -> dict[str, Any] | None:
"""
審查 push event非 PR用 qwen2.5-coder:7b 快速掃描
2026-04-10 Claude Sonnet 4.6: Phase 32 ADR-067 — gitea_webhook_service 呼叫
"""
async with _SEMAPHORE:
prompt = (
f"你是資深程式審查員,請用繁體中文快速審查以下 Git Push。\n"
f"Repository: {repo_name} Branch: {branch}\n\n"
f"=== Commits ===\n{commit_summary}\n\n"
f"=== Changed Files ===\n{files_summary}\n\n"
"請簡要說明1) 有無明顯安全風險 2) 有無破壞性變更 3) 整體品質評估\n"
"格式:每個問題以「⚠️」開頭,如無問題說「✅ Push 品質正常」\n"
"5 行以內,繁體中文。"
)
try:
http = await self._get_http()
resp = await http.post(
f"{settings.OLLAMA_URL}/api/generate",
json={
"model": _MODEL_OLLAMA,
"prompt": prompt,
"stream": False,
"options": {"num_predict": 512, "temperature": 0.1},
},
)
if resp.status_code == 200:
text = resp.json().get("response", "").strip()
issues = text.count("⚠️")
logger.info("push_review_ollama_done", repo=repo_name, branch=branch, issues=issues)
return {"review_text": text, "issues_count": issues, "model": _MODEL_OLLAMA, "provider": "ollama"}
except httpx.TimeoutException:
logger.warning("push_review_ollama_timeout", repo=repo_name)
except Exception as e:
logger.error("push_review_ollama_failed", repo=repo_name, error=str(e))
return None
async def close(self) -> None:
if self._http and not self._http.is_closed:
await self._http.aclose()