feat(schedule): 新增每日零点自动生成日程任务
新增一个后台异步任务,用于在每日零点自动为新的一天生成日程表。 此功能通过 `AsyncTask` 实现,在程序启动时初始化并启动一个循环任务。该任务会计算到下一个零点的时间并等待,然后在零点触发新的日程生成和保存流程,确保日程表能够每日自动更新。
This commit is contained in:
committed by
Windpicker-owo
parent
cd9c46333c
commit
4e75044a0a
@@ -148,6 +148,7 @@ MaiMbot-Pro-Max(第三方改版)
|
|||||||
if global_config.schedule.enable:
|
if global_config.schedule.enable:
|
||||||
logger.info("日程表功能已启用,正在初始化管理器...")
|
logger.info("日程表功能已启用,正在初始化管理器...")
|
||||||
await schedule_manager.load_or_generate_today_schedule()
|
await schedule_manager.load_or_generate_today_schedule()
|
||||||
|
await schedule_manager.start_daily_schedule_generation()
|
||||||
logger.info("日程表管理器初始化成功。")
|
logger.info("日程表管理器初始化成功。")
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import json
|
import json
|
||||||
from datetime import datetime, time
|
import asyncio
|
||||||
|
from datetime import datetime, time, timedelta
|
||||||
from typing import Optional, List, Dict, Any
|
from typing import Optional, List, Dict, Any
|
||||||
from pydantic import BaseModel, ValidationError, validator
|
from pydantic import BaseModel, ValidationError, validator
|
||||||
|
|
||||||
@@ -8,6 +9,8 @@ from src.config.config import global_config, model_config
|
|||||||
from src.llm_models.utils_model import LLMRequest
|
from src.llm_models.utils_model import LLMRequest
|
||||||
from src.common.logger import get_logger
|
from src.common.logger import get_logger
|
||||||
from json_repair import repair_json
|
from json_repair import repair_json
|
||||||
|
from src.manager.async_task_manager import AsyncTask, async_task_manager
|
||||||
|
|
||||||
|
|
||||||
logger = get_logger("schedule_manager")
|
logger = get_logger("schedule_manager")
|
||||||
|
|
||||||
@@ -115,6 +118,18 @@ class ScheduleManager:
|
|||||||
self.today_schedule: Optional[List[Dict[str, Any]]] = None
|
self.today_schedule: Optional[List[Dict[str, Any]]] = None
|
||||||
self.llm = LLMRequest(model_set=model_config.model_task_config.schedule_generator, request_type="schedule")
|
self.llm = LLMRequest(model_set=model_config.model_task_config.schedule_generator, request_type="schedule")
|
||||||
self.max_retries = 3 # 最大重试次数
|
self.max_retries = 3 # 最大重试次数
|
||||||
|
self.daily_task_started = False
|
||||||
|
|
||||||
|
async def start_daily_schedule_generation(self):
|
||||||
|
"""启动每日零点自动生成新日程的任务"""
|
||||||
|
if not self.daily_task_started:
|
||||||
|
logger.info("正在启动每日日程生成任务...")
|
||||||
|
task = DailyScheduleGenerationTask(self)
|
||||||
|
await async_task_manager.add_task(task)
|
||||||
|
self.daily_task_started = True
|
||||||
|
logger.info("每日日程生成任务已成功启动。")
|
||||||
|
else:
|
||||||
|
logger.info("每日日程生成任务已在运行中。")
|
||||||
|
|
||||||
async def load_or_generate_today_schedule(self):
|
async def load_or_generate_today_schedule(self):
|
||||||
# 检查是否启用日程管理功能
|
# 检查是否启用日程管理功能
|
||||||
@@ -130,7 +145,7 @@ class ScheduleManager:
|
|||||||
logger.info(f"从数据库加载今天的日程 ({today_str})。")
|
logger.info(f"从数据库加载今天的日程 ({today_str})。")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
schedule_data = json.loads(schedule_record.schedule_data)
|
schedule_data = json.loads(str(schedule_record.schedule_data))
|
||||||
|
|
||||||
# 使用Pydantic验证日程数据
|
# 使用Pydantic验证日程数据
|
||||||
if self._validate_schedule_with_pydantic(schedule_data):
|
if self._validate_schedule_with_pydantic(schedule_data):
|
||||||
@@ -301,4 +316,39 @@ class ScheduleManager:
|
|||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
class DailyScheduleGenerationTask(AsyncTask):
|
||||||
|
"""每日零点自动生成新日程的任务"""
|
||||||
|
|
||||||
|
def __init__(self, schedule_manager: "ScheduleManager"):
|
||||||
|
super().__init__(task_name="DailyScheduleGenerationTask")
|
||||||
|
self.schedule_manager = schedule_manager
|
||||||
|
|
||||||
|
async def run(self):
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
# 1. 计算到下一个零点的时间
|
||||||
|
now = datetime.now()
|
||||||
|
tomorrow = now.date() + timedelta(days=1)
|
||||||
|
midnight = datetime.combine(tomorrow, time.min)
|
||||||
|
sleep_seconds = (midnight - now).total_seconds()
|
||||||
|
|
||||||
|
logger.info(f"下一次日程生成任务将在 {sleep_seconds:.2f} 秒后运行 (北京时间 {midnight.strftime('%Y-%m-%d %H:%M:%S')})")
|
||||||
|
|
||||||
|
# 2. 等待直到零点
|
||||||
|
await asyncio.sleep(sleep_seconds)
|
||||||
|
|
||||||
|
# 3. 执行日程生成
|
||||||
|
logger.info("到达每日零点,开始为新的一天生成日程...")
|
||||||
|
await self.schedule_manager.generate_and_save_schedule()
|
||||||
|
|
||||||
|
except asyncio.CancelledError:
|
||||||
|
logger.info("每日日程生成任务被取消。")
|
||||||
|
break
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"每日日程生成任务发生未知错误: {e}")
|
||||||
|
# 发生错误后,等待5分钟再重试,避免频繁失败
|
||||||
|
await asyncio.sleep(300)
|
||||||
|
|
||||||
|
|
||||||
schedule_manager = ScheduleManager()
|
schedule_manager = ScheduleManager()
|
||||||
Reference in New Issue
Block a user