diff --git a/.env.example b/.env.example index 7a4490c..28a9ea3 100644 --- a/.env.example +++ b/.env.example @@ -228,9 +228,9 @@ CODE_REVIEW_HERMES_SECONDARY_MODEL=gemma3:4b CODE_REVIEW_HERMES_SECONDARY_TIMEOUT=25 CODE_REVIEW_HERMES_FALLBACK_MODEL=hermes3:latest CODE_REVIEW_HERMES_FALLBACK_TIMEOUT=20 -CODE_REVIEW_HERMES_NUM_PREDICT=768 -CODE_REVIEW_HERMES_MAX_FILES=3 -CODE_REVIEW_HERMES_MAX_CHARS=2500 +CODE_REVIEW_HERMES_NUM_PREDICT=384 +CODE_REVIEW_HERMES_MAX_FILES=2 +CODE_REVIEW_HERMES_MAX_CHARS=900 CODE_REVIEW_AUTO_FIX_ENABLED=true # [選填] 僅本機開發可設 true;正式環境不得允許不安全 internal webhook diff --git a/TODO_NEXT_STEPS.txt b/TODO_NEXT_STEPS.txt index 383d07e..cb035e3 100644 --- a/TODO_NEXT_STEPS.txt +++ b/TODO_NEXT_STEPS.txt @@ -4,6 +4,7 @@ ================================================================================ 【已完成】 + - V10.283 將 Code Review Hermes scan 收斂為 fast compact prompt:預設 2 檔 × 900 字、輸出 384 tokens,仍走 GCP-A → GCP-B → 111 本地矩陣,避免部署後 code_review_hermes 先卡三段 timeout。 - V10.282 補齊 Code Review Hermes scan 本地模型矩陣:掃描階段也走 GCP-A `qwen2.5-coder:7b` → GCP-B `gemma3:4b` → 111 `hermes3:latest`,避免 `hermes3` 在三主機各卡 35s 後只留下 error;Hermes scan 不會啟用 Gemini。 - V10.281 強化 Code Review OpenClaw 本地備援矩陣:主機順序仍為 GCP-A → GCP-B → 111,但改成 GCP-A `qwen2.5-coder:7b`、GCP-B `gemma3:4b`、111 `hermes3:latest`,三段本地 Ollama 全失敗後才允許 Claude/Gemini 備援。 - V10.279 收斂 Code Review Ollama-first 路徑:OpenClaw assessment 預設改 `qwen2.5-coder:7b` + 45s/host timeout,Hermes scan 改 compact snippet + 35s/host timeout,避免三主機各卡 120s 後被迫觸發 Gemini 備援。 diff --git a/config.py b/config.py index c25acaf..bde958a 100644 --- a/config.py +++ b/config.py @@ -320,7 +320,7 @@ YOUTUBE_API_KEY = os.getenv('YOUTUBE_API_KEY', '') # ========================================== # 系統版本與路徑 # ========================================== -SYSTEM_VERSION = "V10.282" +SYSTEM_VERSION = "V10.283" 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 ad6a3e1..68acbd5 100644 --- a/docs/AI_INTELLIGENCE_MODULE_SOT.md +++ b/docs/AI_INTELLIGENCE_MODULE_SOT.md @@ -2,7 +2,7 @@ > **最後更新**: 2026-05-19 (台北時間) > **狀態**: 🟢 四 AI Agent 自動化閉環已落地;LLM 路由紅線升級為 Ollama-first 三主機級聯,Gemini 僅備援 / 鎖定場景 -> **適用版本**: V10.282 +> **適用版本**: V10.283 --- @@ -17,7 +17,7 @@ - NemoTron qwen3 dispatch 的 `/api/chat` tool-calling 路徑也必須同一請求最多嘗試三台 Ollama,第一台失敗要 `mark_unhealthy()` 後再試下一台,最後才 fallback NIM。 - PPT vision、PPT 文案 final fallback、MCP 離線 final fallback 等特殊 Ollama 路徑也不得只打單一 host;如需 `/api/generate`,一律透過 `OllamaService.generate()`。 - Code Review pipeline 也必須 Ollama-first:Hermes scan 與 OpenClaw assessment 都走 `OllamaService` 三主機 retry;Gemini telemetry 只能以 `code_review_openclaw_gemini` 出現,表示 Ollama/可選 Claude 備援都失敗後才啟用。 -- Code Review 的 OpenClaw assessment 預設使用 `qwen2.5-coder:7b` 與 45s/host timeout;Hermes scan 只送 compact snippet(預設 3 檔、每檔 2500 字)並使用 35s/host timeout,避免三主機各卡 120s 後把正常 code review 推進 Gemini 備援。 +- Code Review 的 OpenClaw assessment 預設使用 `qwen2.5-coder:7b` 與 45s/host timeout;Hermes scan 只送 fast compact snippet(預設 2 檔、每檔 900 字)並使用 35s primary timeout,避免大 prompt 讓三主機依序超時後留下錯誤遙測。 - Code Review Hermes scan 也使用同一條本地模型矩陣:GCP-A `qwen2.5-coder:7b`、GCP-B `gemma3:4b`、111 `hermes3:latest`;不啟用 Gemini 備援,三段本地掃描失敗時只回空 findings 並交由 OpenClaw 本地矩陣續跑。 - Code Review OpenClaw assessment 保持主機順序 GCP-A → GCP-B → 111,但可使用主機適配本地模型:GCP-A `qwen2.5-coder:7b`、GCP-B `gemma3:4b`、111 `hermes3:latest`;三段本地 Ollama 全失敗後才允許雲端備援。 - OpenClaw Telegram Q&A 主路徑也不得綁單一 host:`_call_qwen3_qa()` 必須透過 `OllamaService` 跑 GCP-A → GCP-B → 111,並把實際落點寫入 `ai_calls.provider`。 diff --git a/services/code_review_pipeline_service.py b/services/code_review_pipeline_service.py index b8982c7..cd776de 100644 --- a/services/code_review_pipeline_service.py +++ b/services/code_review_pipeline_service.py @@ -82,9 +82,9 @@ CODE_REVIEW_HERMES_PRIMARY_TIMEOUT = int( ) CODE_REVIEW_HERMES_SECONDARY_TIMEOUT = int(os.getenv("CODE_REVIEW_HERMES_SECONDARY_TIMEOUT", "25")) CODE_REVIEW_HERMES_FALLBACK_TIMEOUT = int(os.getenv("CODE_REVIEW_HERMES_FALLBACK_TIMEOUT", "20")) -CODE_REVIEW_HERMES_NUM_PREDICT = int(os.getenv("CODE_REVIEW_HERMES_NUM_PREDICT", "768")) -CODE_REVIEW_HERMES_MAX_FILES = int(os.getenv("CODE_REVIEW_HERMES_MAX_FILES", "3")) -CODE_REVIEW_HERMES_MAX_CHARS = int(os.getenv("CODE_REVIEW_HERMES_MAX_CHARS", "2500")) +CODE_REVIEW_HERMES_NUM_PREDICT = int(os.getenv("CODE_REVIEW_HERMES_NUM_PREDICT", "384")) +CODE_REVIEW_HERMES_MAX_FILES = int(os.getenv("CODE_REVIEW_HERMES_MAX_FILES", "2")) +CODE_REVIEW_HERMES_MAX_CHARS = int(os.getenv("CODE_REVIEW_HERMES_MAX_CHARS", "900")) INTERNAL_TOKEN = os.getenv("INTERNAL_WEBHOOK_TOKEN", "") AUTO_FIX_ENABLED = os.getenv("CODE_REVIEW_AUTO_FIX_ENABLED", "true").lower() == "true" ALLOW_INSECURE_WEBHOOK = os.getenv("MOMO_ALLOW_INSECURE_INTERNAL_WEBHOOK_FOR_DEV", "").lower() == "true" diff --git a/tests/test_code_review_claude_routing.py b/tests/test_code_review_claude_routing.py index cc15751..8aebddc 100644 --- a/tests/test_code_review_claude_routing.py +++ b/tests/test_code_review_claude_routing.py @@ -231,9 +231,9 @@ def test_code_review_ollama_defaults_use_fast_local_model(monkeypatch): assert svc_mod.CODE_REVIEW_HERMES_SECONDARY_TIMEOUT == 25 assert svc_mod.CODE_REVIEW_HERMES_FALLBACK_MODEL == "hermes3:latest" assert svc_mod.CODE_REVIEW_HERMES_FALLBACK_TIMEOUT == 20 - assert svc_mod.CODE_REVIEW_HERMES_NUM_PREDICT == 768 - assert svc_mod.CODE_REVIEW_HERMES_MAX_FILES == 3 - assert svc_mod.CODE_REVIEW_HERMES_MAX_CHARS == 2500 + assert svc_mod.CODE_REVIEW_HERMES_NUM_PREDICT == 384 + assert svc_mod.CODE_REVIEW_HERMES_MAX_FILES == 2 + assert svc_mod.CODE_REVIEW_HERMES_MAX_CHARS == 900 def test_openclaw_uses_secondary_local_model_before_gemini(monkeypatch): @@ -323,7 +323,7 @@ def test_hermes_scan_uses_compact_prompt_and_short_timeout(monkeypatch): kwargs = fake_ollama.generate.call_args.kwargs assert kwargs["model"] == "qwen2.5-coder:7b" assert kwargs["timeout"] == 7 - assert kwargs["options"] == {"num_predict": 768} + assert kwargs["options"] == {"num_predict": 384} prompt = kwargs["prompt"] assert "services/a.py" in prompt assert "services/b.py" in prompt