Files
MoviePilot/app/agent/tools/impl/run_scheduler.py
T
jxxghp 7e851dbfa7 refactor(chain): 处理链功能域 mixin 化,清理未使用导入并根治兼容层循环导入
- ChainBase 拆分为 RecognitionMixin/MessageProcessingMixin/NotificationMixin
- TransferChain 拆分为 7 个功能 mixin(_mixins.py),SubscribeChain 音乐订阅域拆出 _music.py
- 斜杠命令交互四件套收敛为 InteractionChainMixin 委托,会话管理器移至 application 层,chain 层不再 re-export
- 模块基础类收敛到 app/modules/_base(notification/mediaserver 语义重命名)
- 清理 app/chain/__init__.py 24 个未使用导入,修正 49 处测试 patch 目标到实际命名空间
- 兼容层 legacy 符号不再并入 __all__,根治 schemas 初始化反向拉起 application.transfer 的循环导入
- 修复 bangumi 集数为字符串时 set_bangumi_info 抛 TypeError
- 新增重复代码等架构门禁测试;capability 清单校验排除下划线内部目录
2026-08-16 16:30:16 +08:00

82 lines
3.0 KiB
Python

"""运行定时服务工具"""
from typing import Optional, Type
from pydantic import BaseModel, Field
from app.agent.tools.base import MoviePilotTool
from app.agent.tools.tags import ToolTag
from app.runtime.log import logger
class RunSchedulerInput(BaseModel):
"""运行定时服务工具的输入参数模型"""
job_id: str = Field(
...,
description=(
"Runtime scheduler job ID returned by query_schedulers. Do not pass an "
"autonomous agent task ID or an agent-task-* runtime ID."
),
)
class RunSchedulerTool(MoviePilotTool):
"""立即运行系统、插件或工作流注册的定时服务。"""
name: str = "run_scheduler"
tags: list[str] = [
ToolTag.Write,
ToolTag.Scheduler,
ToolTag.Admin,
]
description: str = (
"Manually trigger a MoviePilot system, plugin, or workflow scheduler service by "
"the runtime job_id returned from query_schedulers. This tool does not run "
"user-created autonomous agent tasks; use run_agent_task with an integer task_id."
)
args_schema: Type[BaseModel] = RunSchedulerInput
require_admin: bool = True
def get_tool_message(self, **kwargs: object) -> Optional[str]:
"""根据运行参数生成友好的提示消息。"""
job_id = kwargs.get("job_id", "")
return f"运行定时服务 (ID: {job_id})"
@staticmethod
def _run_scheduler_sync(job_id: str) -> tuple[bool, str]:
"""同步触发定时服务,避免调度器扫描阻塞事件循环。"""
from app.application.scheduling import (
list_scheduler_jobs,
start_scheduler_job,
)
for scheduler_item in list_scheduler_jobs():
if scheduler_item.id == job_id:
start_scheduler_job(job_id)
return True, scheduler_item.name
return False, ""
async def run(self, job_id: str, **kwargs: object) -> str:
"""立即运行非 Agent 自主任务的运行时定时服务。"""
logger.info(f"执行工具: {self.name}, 参数: job_id={job_id}")
try:
from app.application.scheduling import AGENT_TASK_JOB_PREFIX
if job_id.startswith(f"{AGENT_TASK_JOB_PREFIX}-"):
return (
"Agent 自主定时任务不能通过 run_scheduler 运行,"
"请使用 query_agent_tasks 查询整数 task_id 后调用 run_agent_task"
)
job_exists, job_name = await self.run_blocking(
"workflow", self._run_scheduler_sync, job_id
)
if not job_exists:
return f"定时服务 ID {job_id} 不存在,请使用 query_schedulers 工具查询可用的定时服务"
return f"成功触发定时服务:{job_name} (ID: {job_id})"
except Exception as e:
logger.error(f"运行定时服务失败: {e}", exc_info=True)
return f"运行定时服务时发生错误: {str(e)}"