diff --git a/.env.example b/.env.example index e65ee7a..55fc7ff 100644 --- a/.env.example +++ b/.env.example @@ -21,10 +21,13 @@ DISABLE_LOGIN=false # ========================================== TELEGRAM_BOT_TOKEN=your_telegram_bot_token TELEGRAM_CHAT_IDS=["chat_id_1","chat_id_2","chat_id_3"] +# [選填] 舊腳本 fallback;新流程優先使用 TELEGRAM_CHAT_IDS JSON 陣列 +TELEGRAM_CHAT_ID=chat_id_1 # ========================================== # Line Notify 設定 # ========================================== +LINE_ENABLED=false LINE_CHANNEL_ACCESS_TOKEN=your_line_channel_access_token LINE_GROUP_ID=your_line_group_id @@ -51,6 +54,8 @@ NGROK_AUTH_TOKEN=your_ngrok_auth_token # --- Alert Webhook --- ALERT_WEBHOOK_USER=alertmanager ALERT_WEBHOOK_PASSWORD=your_secure_webhook_password_here +# [預設 true] Alertmanager 告警自動修復開關;正式環境需配合 cooldown 與 allowlist +AUTO_FIX_ENABLED=true # --- GitLab CI/CD --- GITLAB_URL=http://192.168.0.110:8929 @@ -65,6 +70,14 @@ GITLAB_PROJECT_ID=1 # 如果部署在 HTTPS 環境,設為 true USE_HTTPS=false +# ========================================== +# Gunicorn Runtime 設定 +# ========================================== +# [預設 4] Web worker 數;正式環境需配合 PostgreSQL pool 上限 +WEB_CONCURRENCY=4 +# [預設 300] 長查詢 / 報表匯出 timeout 秒數 +GUNICORN_TIMEOUT=300 + # ========================================== # Database Settings # ========================================== @@ -101,7 +114,7 @@ HERMES_URL=http://192.168.0.111:11434 HERMES_TIMEOUT=120 # [預設 HERMES_URL] Embedding 服務主機(ADR-003 對齊:embedding 走 Hermes 主機) -# EMBEDDING_HOST=http://192.168.0.111:11434 +EMBEDDING_HOST=http://192.168.0.111:11434 # [預設 45] Embedding API timeout;優先使用 Ollama /api/embed,舊節點 fallback /api/embeddings EMBEDDING_TIMEOUT=45 @@ -133,6 +146,7 @@ ELEPHANT_ALPHA_AUTO_ESCALATION_ENABLED=true ELEPHANT_ALPHA_HERMES_URL=http://192.168.0.111:11434 ELEPHANT_ALPHA_HERMES_MODEL=hermes3:latest ELEPHANT_ALPHA_NEMOTRON_NIM_ENDPOINT=https://integrate.api.nvidia.com/v1 +ELEPHANT_ALPHA_URL=https://integrate.api.nvidia.com/v1/chat/completions ELEPHANT_ALPHA_OPENCLAW_GEMINI_ENDPOINT=https://generativelanguage.googleapis.com/v1beta # ── Google Gemini API ─────────────────────────────────────────────────────── @@ -165,6 +179,12 @@ INITIAL_ADMIN_PASSWORD=your_initial_admin_password_here # 不設則所有 /bot/api/* 端點拒絕請求 BOT_API_TOKEN=your_bot_api_token_here +# [選填] Post-deploy AI code review pipeline 自動修復開關 +CODE_REVIEW_AUTO_FIX_ENABLED=false + +# [選填] 僅本機開發可設 true;正式環境不得允許不安全 internal webhook +MOMO_ALLOW_INSECURE_INTERNAL_WEBHOOK_FOR_DEV=false + # [選填] AIOps SSH Jump 跳板設定(services/jump_executor.py) SSH_JUMP_HOST=192.168.0.110 SSH_JUMP_USER=wooo @@ -206,6 +226,7 @@ ELEPHANT_ALPHA_SSH_KEY_PATH=config/autoheal_id_ed25519 ELEPHANT_ALPHA_SSH_PORT=22 ELEPHANT_ALPHA_SSH_CONNECT_TIMEOUT=10 ELEPHANT_ALPHA_SSH_COMMAND_TIMEOUT=60 +ELEPHANT_ALPHA_ALLOWED_SSH_HOSTS=192.168.0.188 # [選填] 自愈節流與狀態快取 ELEPHANT_ALPHA_CACHE_DB=:memory: @@ -220,6 +241,16 @@ ELEPHANT_TIMEOUT=120 NVIDIA_API_KEY=your_nvidia_api_key_here INTERNAL_WEBHOOK_TOKEN=your_internal_webhook_token_here +# [選填] EventRouter 失敗佇列與重播策略 +MOMO_EVENT_ROUTER_QUEUE=/app/data/event_router_failed_deliveries.jsonl +MOMO_EVENT_ROUTER_DEFAULT_DEDUP_SEC=0 +MOMO_EVENT_ROUTER_REPLAY_ON_SUCCESS=true +MOMO_EVENT_ROUTER_REPLAY_LIMIT=3 + +# [選填] AI 自動化 Smoke 歷史保存 +MOMO_AI_AUTOMATION_SMOKE_HISTORY=/app/data/ai_automation_smoke_history.jsonl +MOMO_AI_AUTOMATION_SMOKE_HISTORY_LIMIT=200 + # [選填] OpenClaw Telegram bot OPENCLAW_BOT_TOKEN=your_openclaw_bot_token_here OPENCLAW_GROUP_ID=-1003940688311 @@ -266,3 +297,13 @@ PG_SYNC_INTERVAL=300 # [選填] 外部 BI 連結(模板全域變數) METABASE_URL=https://mo.wooo.work/metabase GRIST_URL=https://grist.wooo.work + +# ────────────────────────────────────────────────────────────────────────── +# n8n Workflow Automation(monitoring profile) +# ────────────────────────────────────────────────────────────────────────── + +N8N_HOST=192.168.0.110 +N8N_PROTOCOL=http +N8N_WEBHOOK_BASE_URL=http://192.168.0.110:5678/ +N8N_USER=admin +N8N_PASSWORD=change-me diff --git a/docs/ELEPHANT_ALPHA_SETUP.md b/docs/ELEPHANT_ALPHA_SETUP.md index 2d7a210..7509fb8 100644 --- a/docs/ELEPHANT_ALPHA_SETUP.md +++ b/docs/ELEPHANT_ALPHA_SETUP.md @@ -232,7 +232,8 @@ AutonomousTrigger( ``` ### 2. **Routing Strategies** -Modify routing behavior in `services/elephant_alpha_decision_router.py`: +Modify routing behavior in `services/event_router.py` and `services/elephant_alpha_orchestrator.py`. +`services/elephant_alpha_decision_router.py` was removed during Phase 3f cleanup and must not be reintroduced: ```python # Add custom routing strategy diff --git a/tests/test_phase3f_cleanup_contracts.py b/tests/test_phase3f_cleanup_contracts.py new file mode 100644 index 0000000..781cdc4 --- /dev/null +++ b/tests/test_phase3f_cleanup_contracts.py @@ -0,0 +1,71 @@ +from pathlib import Path + + +ROOT = Path(__file__).resolve().parents[1] + + +def _env_example_keys() -> set[str]: + keys = set() + for raw_line in (ROOT / ".env.example").read_text(encoding="utf-8").splitlines(): + line = raw_line.strip() + if not line or line.startswith("#") or "=" not in line: + continue + key, _value = line.split("=", 1) + keys.add(key.strip()) + return keys + + +def test_phase3f_orphan_ai_services_stay_removed(): + orphan_services = [ + "services/elephant_alpha_decision_router.py", + "services/telegram_ai_integration.py", + "services/watcher_agent.py", + ] + + assert [path for path in orphan_services if (ROOT / path).exists()] == [] + + +def test_active_guides_do_not_point_to_removed_ai_services(): + active_guides = [ + ROOT / "docs" / "ELEPHANT_ALPHA_SETUP.md", + ] + removed_modules = [ + "services/telegram_ai_integration.py", + "services/watcher_agent.py", + ] + + for guide in active_guides: + content = guide.read_text(encoding="utf-8") + assert "Modify routing behavior in `services/elephant_alpha_decision_router.py`" not in content + for module_path in removed_modules: + assert module_path not in content + + +def test_env_example_documents_runtime_and_ai_automation_variables(): + expected_keys = { + "AUTO_FIX_ENABLED", + "CODE_REVIEW_AUTO_FIX_ENABLED", + "ELEPHANT_ALPHA_ALLOWED_SSH_HOSTS", + "ELEPHANT_ALPHA_URL", + "EMBEDDING_HOST", + "EMBEDDING_TIMEOUT", + "GUNICORN_TIMEOUT", + "LINE_ENABLED", + "MOMO_AI_AUTOMATION_SMOKE_HISTORY", + "MOMO_AI_AUTOMATION_SMOKE_HISTORY_LIMIT", + "MOMO_ALLOW_INSECURE_INTERNAL_WEBHOOK_FOR_DEV", + "MOMO_EVENT_ROUTER_DEFAULT_DEDUP_SEC", + "MOMO_EVENT_ROUTER_QUEUE", + "MOMO_EVENT_ROUTER_REPLAY_LIMIT", + "MOMO_EVENT_ROUTER_REPLAY_ON_SUCCESS", + "N8N_HOST", + "N8N_PASSWORD", + "N8N_PROTOCOL", + "N8N_USER", + "N8N_WEBHOOK_BASE_URL", + "OLLAMA_EMBED_TIMEOUT", + "TELEGRAM_CHAT_ID", + "WEB_CONCURRENCY", + } + + assert expected_keys <= _env_example_keys()