This commit is contained in:
@@ -320,7 +320,7 @@ YOUTUBE_API_KEY = os.getenv('YOUTUBE_API_KEY', '')
|
||||
# ==========================================
|
||||
# 系統版本與路徑
|
||||
# ==========================================
|
||||
SYSTEM_VERSION = "V10.273"
|
||||
SYSTEM_VERSION = "V10.274"
|
||||
LOG_FILE_PATH = os.path.join(BASE_DIR, 'logs/system.log')
|
||||
public_url = PUBLIC_URL # 用於模板顯示
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
> **最後更新**: 2026-05-19 (台北時間)
|
||||
> **狀態**: 🟢 四 AI Agent 自動化閉環已落地;LLM 路由紅線升級為 Ollama-first 三主機級聯,Gemini 僅備援 / 鎖定場景
|
||||
> **適用版本**: V10.272
|
||||
> **適用版本**: V10.274
|
||||
|
||||
---
|
||||
|
||||
@@ -108,6 +108,7 @@ SQL漏斗(~300筆)
|
||||
- ElephantAlpha L3 HITL 只允許發送有實證、可審核、可行動的升級告警;價格類 trigger 無 Hermes 具體威脅時,只記錄 suppressed escalation telemetry 與 cooldown,不寫 pending `human_review`,不發 Telegram 空告警。
|
||||
- `resource_optimization` 不再交給 LLM 生成「預期效益 / 已執行」敘事。此 trigger 必須先由程式量測 `action_plans` backlog、P1/P2 數、pending_review、逾時項目與 CPU load;只有 CPU 達門檻、P1/P2 積壓或逾時積壓才發 Telegram「資源壓力告警」。單純 queue 大但 CPU 正常只記錄 telemetry,不派發 Hermes/NemoTron、不宣稱 48 小時效益。
|
||||
- `resource_optimization` 會先執行 `ActionPlanHygieneService` 清理過期噪音:只關閉超過 72 小時的 `code_review_fix` / `openclaw_recommendation` 類 advisory action_plans,以及 NemoTron `direct_response/reply_simple` 舊聊天回覆計畫;將狀態改為 `auto_disabled` 或 `rejected` 並寫入 `metadata_json.hygiene_history`。不刪資料,也不碰 NemoTron human_review / pricing / tool action 類業務行動。
|
||||
- `momo-scheduler` 每 6 小時固定執行 `run_action_plan_hygiene_task()`,讓過期 advisory action_plans 的關閉不再依賴 `resource_optimization` 告警觸發;排程失敗會經 EventRouter 發送 `action_plan_hygiene_failure`。
|
||||
- `action_plans` 產生端必須防重:Code Review 同一檔案已有 active `code_review_fix` 時不重建;OpenClaw recommendation 會寫入文字 fingerprint 並跳過同一建議;AIOrchestrator 不再把 NemoTron `direct_response/reply_simple` 聊天回覆存成 action plan,真正需工具、審核或執行的 NemoTron action 才能進 queue。
|
||||
- OpenClaw/Hermes embedding 優先呼叫 Ollama `/api/embed`,只在舊節點不支援時 fallback `/api/embeddings`;timeout 由 `EMBEDDING_TIMEOUT` / `OLLAMA_EMBED_TIMEOUT` 控制。
|
||||
- PPT 自動產線由 `momo-scheduler` 依節奏執行 `run_ppt_auto_generation_task(schedule_kind)`:每日 20:30 產日報、週一 20:40 產週報/市場情報、每月 1 日 20:50 產月報與管理型簡報、季初 21:00 產季報、半年初 21:10 產半年報、年初 21:20 產年報,再交給 22:00 `ppt_vision_audit` 做視覺審核;每次嘗試會寫入 `ppt_generation_runs`,`/observability/ppt_audit_history` 以精準參數檢查目標版本是否已產生,並可用 `/observability/ppt_audit/generate_missing` 手動補齊缺漏,總開關為 `PPT_AUTO_GENERATION_ENABLED`。PPT vision 需 `PPT_VISION_ENABLED=true` 與容器內 LibreOffice;`/observability/ppt_audit_file/<filename>` 會把 PPTX 轉成 PDF 快取供站內線上預覽,原始 PPTX 仍保留下載。
|
||||
|
||||
@@ -6,7 +6,7 @@ run_scheduler.py — momo-scheduler 容器入口點
|
||||
每 30 分鐘:auto_import、whitepage_check
|
||||
每 1 小時:momo、edm、festival
|
||||
每 4 小時:competitor_price_feeder、icaim_analysis
|
||||
每 6 小時:quality_rescore
|
||||
每 6 小時:quality_rescore、action_plan_hygiene
|
||||
每 12 小時:dedup_batch
|
||||
每 1 天 :db_backup(03:00)、cleanup_agent_context(03:30)、backup_monitor(04:00)、daily_report(09:00)、roi_monthly_report gate(09:05)、ai_smoke_summary(09:10)、observability_daily_summary(09:30)、pchome_match_backfill(10:30)、openclaw_meta_analysis(12:00, Phase 4 降頻)、ppt_auto_generation_daily(20:30)、ppt_vision_audit(22:00)、daily_token_report(23:55)
|
||||
每 1 週 :weekly_strategy(週一 06:00)、ppt_auto_generation_weekly(週一 20:40)
|
||||
@@ -17,6 +17,7 @@ run_scheduler.py — momo-scheduler 容器入口點
|
||||
"""
|
||||
import asyncio
|
||||
import logging
|
||||
import os
|
||||
import threading
|
||||
import time
|
||||
|
||||
@@ -141,6 +142,9 @@ def _register_schedules():
|
||||
schedule.every(6).hours.do(run_quality_rescore_task)
|
||||
logger.info("📅 每 6 小時:quality_rescore")
|
||||
|
||||
schedule.every(6).hours.do(run_action_plan_hygiene_task)
|
||||
logger.info("📅 每 6 小時:action_plan_hygiene(關閉過期 advisory action_plans)")
|
||||
|
||||
schedule.every(12).hours.do(run_dedup_batch_task)
|
||||
logger.info("📅 每 12 小時:dedup_batch")
|
||||
|
||||
@@ -364,6 +368,32 @@ def run_expire_stale_reviews():
|
||||
)
|
||||
|
||||
|
||||
def run_action_plan_hygiene_task():
|
||||
"""每 6 小時 — 關閉過期 advisory action_plans,避免 queue 再次膨脹。"""
|
||||
try:
|
||||
from services.action_plan_hygiene import run_action_plan_hygiene
|
||||
|
||||
result = run_action_plan_hygiene()
|
||||
updated = int(result.get("updated_count") or 0)
|
||||
if updated > 0:
|
||||
logger.info(
|
||||
"[ActionPlanHygiene] updated=%d by_source=%s",
|
||||
updated,
|
||||
result.get("by_source"),
|
||||
)
|
||||
else:
|
||||
logger.debug("[ActionPlanHygiene] no stale advisory action plans")
|
||||
except Exception as e:
|
||||
logger.error(f"[ActionPlanHygiene] task failed: {e}", exc_info=True)
|
||||
_notify_scheduler_failure(
|
||||
"run_action_plan_hygiene_task",
|
||||
e,
|
||||
source="Scheduler.ActionPlanHygiene",
|
||||
event_type="action_plan_hygiene_failure",
|
||||
title="Action Plan 過期清理失敗",
|
||||
)
|
||||
|
||||
|
||||
def run_cost_throttle_evaluate():
|
||||
"""每小時 — Phase 20 成本自動節流評估(COST_THROTTLE_ENABLED 預設 OFF)。
|
||||
|
||||
|
||||
@@ -141,6 +141,7 @@ def test_v2_cron_blind_spot_list_has_failure_notifications(monkeypatch):
|
||||
"run_promotion_gate_worker",
|
||||
"run_awaiting_review_push",
|
||||
"run_expire_stale_reviews",
|
||||
"run_action_plan_hygiene_task",
|
||||
"run_cost_throttle_evaluate",
|
||||
"run_cost_throttle_reset_if_new_month",
|
||||
"run_ppt_vision_audit",
|
||||
@@ -159,3 +160,4 @@ def test_roi_ai_smoke_and_daily_report_schedules_stay_staggered():
|
||||
assert 'schedule.every().day.at("09:00").do(run_daily_report_task)' in source
|
||||
assert 'schedule.every().day.at("09:05").do(run_roi_monthly_report_if_new_month)' in source
|
||||
assert 'schedule.every().day.at("09:10").do(run_ai_smoke_daily_summary_task)' in source
|
||||
assert "schedule.every(6).hours.do(run_action_plan_hygiene_task)" in source
|
||||
|
||||
Reference in New Issue
Block a user