fix(code-review): 修復 Hermes 401 與 OpenClaw GEMINI_API_KEY 缺失
All checks were successful
CD Pipeline / deploy (push) Successful in 1m17s

Hermes 掃描:改直呼內網 http://192.168.0.111:11434/api/generate
(棄用 ai_provider_service,避開公網 Ollama 401 認證問題)

OpenClaw 評估:Gemini 優先,降級用 elephant_service(OpenRouter)
(容器內無 GEMINI_API_KEY,但 OPENROUTER_API_KEY 一定存在)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
ogt
2026-04-21 21:16:44 +08:00
parent 2e0de960ce
commit 1f7b903d36

View File

@@ -189,10 +189,10 @@ class CodeReviewPipeline:
# ── Step 2Hermes 掃描 ───────────────────────────────────────────────────
def _hermes_scan(self, files: Dict[str, str]) -> List[Dict]:
"""直呼內網 Ollamahttp://192.168.0.111:11434免認證"""
try:
from services.ai_provider import ai_provider_service
import requests as _req
# 最多送 4 個檔案給 Hermes避免 context overflow
files_text = "\n\n".join(
f"### {name}\n```python\n{content}\n```"
for name, content in list(files.items())[:4]
@@ -212,23 +212,21 @@ class CodeReviewPipeline:
只輸出 JSON 陣列,不含其他文字。無問題時輸出 []"""
resp = ai_provider_service.generate(
prompt=prompt,
provider="ollama",
model="hermes3:latest",
temperature=0.1,
resp = _req.post(
"http://192.168.0.111:11434/api/generate",
json={"model": "hermes3:latest", "prompt": prompt,
"stream": False, "options": {"temperature": 0.1}},
timeout=120,
)
if not (resp and resp.success):
logger.warning("[CodeReview] Hermes 未回應: %s", getattr(resp, "error", ""))
return []
resp.raise_for_status()
raw = resp.json().get("response", "").strip()
match = re.search(r"\[.*\]", resp.content, re.DOTALL)
match = re.search(r"\[.*\]", raw, re.DOTALL)
if not match:
logger.warning("[CodeReview] Hermes 回應無 JSON: %s", raw[:200])
return []
findings = json.loads(match.group())
# 更新 severity 計數
for f in findings:
sev = f.get("severity", "LOW").lower()
if sev in self.state["severity_summary"]:
@@ -244,46 +242,64 @@ class CodeReviewPipeline:
# ── Step 3OpenClaw 評估 ──────────────────────────────────────────────────
def _openclaw_assess(self, files: Dict[str, str], findings: List[Dict]) -> str:
if not GEMINI_API_KEY:
logger.warning("[CodeReview] GEMINI_API_KEY 未設定,跳過 OpenClaw")
return ""
try:
import google.generativeai as genai
genai.configure(api_key=GEMINI_API_KEY)
model = genai.GenerativeModel(
model_name=REVIEW_MODEL,
generation_config=genai.types.GenerationConfig(
temperature=0.3, max_output_tokens=1500,
),
system_instruction=(
"你是 OpenClaw 程式碼品質戰略分析師,以技術主管視角評估部署後程式碼。"
"語言:繁體中文。風格:精準、數據導向、可執行建議。"
),
)
sev = self.state["severity_summary"]
findings_json = json.dumps(findings[:8], ensure_ascii=False, indent=2)
files_list = "\n".join(f"- {k} ({len(v)} 字元)" for k, v in list(files.items())[:5])
"""
優先用 GeminiGEMINI_API_KEY降級用 ElephantAlpha via OpenRouter
(容器內 OPENROUTER_API_KEY 一定存在)
"""
sev = self.state["severity_summary"]
findings_json = json.dumps(findings[:8], ensure_ascii=False, indent=2)
files_list = "\n".join(f"- {k} ({len(v)} 字元)" for k, v in list(files.items())[:5])
prompt = f"""【部署資訊】Commit {self.commit_sha[:8]} @ {self.branch}
system = (
"你是 OpenClaw 程式碼品質戰略分析師,以技術主管視角評估部署後程式碼。"
"語言:繁體中文。風格:精準、數據導向、可執行建議。"
)
user_prompt = f"""【部署】Commit {self.commit_sha[:8]} @ {self.branch}
【變更檔案】
{files_list}
【Hermes 掃描摘要】CRITICAL={sev['critical']} HIGH={sev['high']} MEDIUM={sev['medium']} LOW={sev['low']}
Hermes 詳細問題】
【問題明細
{findings_json}
請產出程式碼品質評估(使用 HTML <b> 標題150字以內
<b>🔍 整體風險等級</b>(一句理由)
<b>⚠️ 最需關注問題</b>TOP 2
<b>💡 架構優化方向</b>1條長期建議
<b>✅ 本次部署亮點</b>"""
<b>🔍 整體風險等級</b>CRITICAL / HIGH / MEDIUM / LOW一句理由
<b>⚠️ 最需關注問題</b>TOP 2具體說明
<b>💡 架構優化方向</b>1 條長期建議)
<b>✅ 本次部署亮點</b>(值得肯定的地方)"""
# 優先 Gemini
if GEMINI_API_KEY:
try:
import google.generativeai as genai
genai.configure(api_key=GEMINI_API_KEY)
model = genai.GenerativeModel(
model_name=REVIEW_MODEL,
generation_config=genai.types.GenerationConfig(
temperature=0.3, max_output_tokens=1500,
),
system_instruction=system,
)
resp = model.generate_content(user_prompt, request_options={"timeout": 90})
return resp.text or ""
except Exception as e:
logger.warning("[CodeReview] OpenClaw Gemini 失敗,降級 ElephantAlpha: %s", e)
resp = model.generate_content(prompt, request_options={"timeout": 90})
return resp.text or ""
# 降級ElephantAlpha via OpenRouterOPENROUTER_API_KEY 容器內一定有)
try:
from services.elephant_service import elephant_service
resp = elephant_service.generate(
prompt=user_prompt,
system_prompt=system,
temperature=0.3,
timeout=90,
)
if resp.success:
return resp.content or ""
except Exception as e:
logger.warning("[CodeReview] OpenClaw 評估失敗: %s", e)
return ""
logger.warning("[CodeReview] OpenClaw ElephantAlpha 降級也失敗: %s", e)
return ""
# ── Step 4ElephantAlpha 決策 ─────────────────────────────────────────────