From acef0fa6ffb9574a71c1ff7f52711c5b5752ce3e Mon Sep 17 00:00:00 2001 From: OoO Date: Wed, 13 May 2026 12:59:29 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=88=E4=BD=8F=20runtime=20=E7=92=B0?= =?UTF-8?q?=E5=A2=83=E8=AE=8A=E6=95=B8=E6=96=87=E4=BB=B6=E5=A5=91=E7=B4=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env.example | 24 +++++++++++ tests/test_phase3f_cleanup_contracts.py | 55 +++++++++++++++++++++++++ 2 files changed, 79 insertions(+) diff --git a/.env.example b/.env.example index 9324b2c..4e19b39 100644 --- a/.env.example +++ b/.env.example @@ -272,11 +272,15 @@ MOMO_AI_AUTOMATION_SMOKE_HISTORY_LIMIT=200 # [選填] OpenClaw Telegram bot OPENCLAW_BOT_TOKEN=your_openclaw_bot_token_here +TELEGRAM_BOT_USERNAME=@OpenClawAwoooI_Bot OPENCLAW_BOT_USERNAME=@OpenClawAwoooI_Bot OPENCLAW_GROUP_ID=-1003940688311 OPENCLAW_ALLOWED_USERS= +OPENCLAW_ADMIN_USER_IDS= # [預設 1] 舊行為:空白名單仍允許私訊;正式環境建議設 0 並填 OPENCLAW_ALLOWED_USERS OPENCLAW_ALLOW_PRIVATE_WITHOUT_WHITELIST=1 +# [預設 24] PPT 報表快取保留時間(小時) +OPENCLAW_PPT_CACHE_TTL_HOURS=24 # [預設 OFF] ADR-019 agent dispatch;啟用後只讓白名單 cmd 轉 NL agent 處理 OPENCLAW_AGENT_DISPATCH=0 OPENCLAW_AGENT_DISPATCH_CMDS=sales,top,vendor @@ -287,15 +291,30 @@ YOUTUBE_API_KEY= GEMINI_TIMEOUT=60 # [預設 OFF] AI runtime feature flags;未完成部署驗收前不要在正式環境打開 +AI_CALL_LOGGING_ENABLED=true MODEL_ROUTER_ENABLED=false COST_THROTTLE_ENABLED=false +COST_THROTTLE_PROJECT_RATIO=1.10 +COST_UNTHROTTLE_PROJECT_RATIO=0.95 RAG_ENABLED=false +RAG_DEFAULT_THRESHOLD=0.85 +RAG_DEFAULT_TOP_K=5 +RAG_EMBED_MODEL=bge-m3:latest +RAG_EMBED_DIM=1024 +RAG_EMBED_NORMALIZE=true PPT_VISION_ENABLED=false +PPT_VISION_MODEL=minicpm-v:latest +PPT_VISION_TIMEOUT=60 DEEPSEEK_DIRECT_ENABLED=false DEEPSEEK_API_KEY= DEEPSEEK_BASE_URL=https://api.deepseek.com/v1 DEEPSEEK_MODEL=deepseek-chat DEEPSEEK_TIMEOUT=60 +OPENCLAW_DAILY_HERMES_TEMPLATE=true +OPENCLAW_OLLAMA_MODEL=qwen2.5-coder:7b +PROMOTION_PENDING_BATCH_SIZE=50 +AWAITING_REVIEW_PUSH_BATCH=5 +TELEGRAM_ADMIN_CHAT_ID= # ────────────────────────────────────────────────────────────────────────── # Ollama / MCP / 密碼政策 @@ -315,6 +334,8 @@ OPENCLAW_QA_OLLAMA_FIRST=true OPENCLAW_QA_OLLAMA_MODEL=qwen3:14b OPENCLAW_QA_OLLAMA_HOST=http://34.143.170.20:11434 OPENCLAW_QA_OLLAMA_TIMEOUT=60 +NEMOTRON_OLLAMA_FIRST=true +NEMOTRON_OLLAMA_MODEL=qwen3:14b NEMOTRON_OLLAMA_TIMEOUT=180 # [預設 OFF] MCP Router;需先部署 docker-compose.mcp.yml 並完成健康檢查再開 @@ -323,6 +344,9 @@ MCP_POSTGRES_URL=http://127.0.0.1:3001 MCP_FIRECRAWL_URL=http://127.0.0.1:3002 MCP_OMNISEARCH_URL=http://127.0.0.1:3003 MCP_FILESYSTEM_URL=http://127.0.0.1:3004 +MCP_TIMEOUT_SEC=30 +MCP_CACHE_TTL_SEC=3600 +MCP_MAX_RESULT_BYTES=65536 MCP_CACHE_TTL_HOURS=24 MCP_GEMINI_MODEL=gemini-2.0-flash diff --git a/tests/test_phase3f_cleanup_contracts.py b/tests/test_phase3f_cleanup_contracts.py index 1457c40..997b836 100644 --- a/tests/test_phase3f_cleanup_contracts.py +++ b/tests/test_phase3f_cleanup_contracts.py @@ -16,6 +16,29 @@ def _env_example_keys() -> set[str]: return keys +def _runtime_env_keys_from_code() -> set[str]: + pattern = re.compile(r"""os\.(?:getenv|environ\.get)\(\s*['"]([A-Z][A-Z0-9_]+)['"]""") + scan_paths = [ + ROOT / "app.py", + ROOT / "config.py", + ROOT / "scheduler.py", + ROOT / "run_scheduler.py", + ROOT / "routes", + ROOT / "services", + ROOT / "utils", + ] + + keys = set() + for scan_path in scan_paths: + paths = scan_path.rglob("*.py") if scan_path.is_dir() else [scan_path] + for path in paths: + if not path.exists() or "__pycache__" in path.parts: + continue + content = path.read_text(encoding="utf-8", errors="ignore") + keys.update(match.group(1) for match in pattern.finditer(content)) + return keys + + def test_phase3f_orphan_ai_services_stay_removed(): orphan_services = [ "services/elephant_alpha_decision_router.py", @@ -44,9 +67,13 @@ def test_active_guides_do_not_point_to_removed_ai_services(): def test_env_example_documents_runtime_and_ai_automation_variables(): expected_keys = { + "AI_CALL_LOGGING_ENABLED", "AUTO_FIX_ENABLED", + "AWAITING_REVIEW_PUSH_BATCH", "CODE_REVIEW_AUTO_FIX_ENABLED", "COST_THROTTLE_ENABLED", + "COST_THROTTLE_PROJECT_RATIO", + "COST_UNTHROTTLE_PROJECT_RATIO", "DEEPSEEK_API_KEY", "DEEPSEEK_BASE_URL", "DEEPSEEK_DIRECT_ENABLED", @@ -69,26 +96,45 @@ def test_env_example_documents_runtime_and_ai_automation_variables(): "MOMO_EVENT_ROUTER_REPLAY_ON_SUCCESS", "MCP_FILESYSTEM_URL", "MCP_FIRECRAWL_URL", + "MCP_CACHE_TTL_SEC", + "MCP_MAX_RESULT_BYTES", "MCP_OMNISEARCH_URL", "MCP_POSTGRES_URL", "MCP_ROUTER_ENABLED", + "MCP_TIMEOUT_SEC", "MODEL_ROUTER_ENABLED", "N8N_HOST", "N8N_PASSWORD", "N8N_PROTOCOL", "N8N_USER", "N8N_WEBHOOK_BASE_URL", + "NEMOTRON_OLLAMA_FIRST", + "NEMOTRON_OLLAMA_MODEL", "NEMOTRON_OLLAMA_TIMEOUT", "OLLAMA_EMBED_TIMEOUT", + "OPENCLAW_ADMIN_USER_IDS", "OPENCLAW_AGENT_DISPATCH", "OPENCLAW_AGENT_DISPATCH_CMDS", "OPENCLAW_ALLOW_PRIVATE_WITHOUT_WHITELIST", + "OPENCLAW_DAILY_HERMES_TEMPLATE", + "OPENCLAW_OLLAMA_MODEL", + "OPENCLAW_PPT_CACHE_TTL_HOURS", "OPENCLAW_QA_OLLAMA_FIRST", "OPENCLAW_QA_OLLAMA_HOST", "OPENCLAW_QA_OLLAMA_MODEL", "OPENCLAW_QA_OLLAMA_TIMEOUT", "PPT_VISION_ENABLED", + "PPT_VISION_MODEL", + "PPT_VISION_TIMEOUT", + "PROMOTION_PENDING_BATCH_SIZE", "RAG_ENABLED", + "RAG_DEFAULT_THRESHOLD", + "RAG_DEFAULT_TOP_K", + "RAG_EMBED_DIM", + "RAG_EMBED_MODEL", + "RAG_EMBED_NORMALIZE", + "TELEGRAM_ADMIN_CHAT_ID", + "TELEGRAM_BOT_USERNAME", "TELEGRAM_CHAT_ID", "WEB_CONCURRENCY", } @@ -96,6 +142,15 @@ def test_env_example_documents_runtime_and_ai_automation_variables(): assert expected_keys <= _env_example_keys() +def test_env_example_documents_runtime_os_env_keys(): + internal_runtime_keys = { + "MOMO_ALLOW_INSECURE_CONFIG_FOR_TESTS", + "PYTEST_CURRENT_TEST", + } + + assert _runtime_env_keys_from_code() - internal_runtime_keys <= _env_example_keys() + + def test_scheduler_does_not_silently_swallow_exceptions(): scheduler_source = (ROOT / "scheduler.py").read_text(encoding="utf-8")