Files
MoviePilot/app/agent/tools/impl/delete_transfer_history.py
T

132 lines
5.4 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""删除整理历史记录工具"""
import asyncio
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.application.agentdata import get_agent_transfer_history_port
from app.application.chain.data import get_chain_transfer_execution_port
from app.application.transfer.execution import (
TransferExecutionCommand,
TransferRetryRequestResult,
)
from app.chain.storage import StorageChain
from app.runtime.log import logger
from app.schemas.workflow import FileItem
class DeleteTransferHistoryInput(BaseModel):
"""删除整理历史记录工具的输入参数模型"""
history_id: int = Field(
..., description="The ID of the transfer history record to delete"
)
def _delete_history_destination_file(fileitem: FileItem) -> tuple[bool, bool]:
"""在存储 worker 内完成旧目标检查和删除,保持历史删除前的顺序。"""
storage_chain = StorageChain()
if not storage_chain.exists(fileitem):
return False, False
return True, bool(storage_chain.delete_media_file(fileitem))
def _request_transfer_retry(
*,
history_id: int,
task_id: str,
user_id: str,
) -> TransferRetryRequestResult:
"""在线程池中登记 durable 重试,避免 Agent 事件循环执行同步数据库 I/O。"""
return TransferExecutionCommand(
get_chain_transfer_execution_port()
).request_retry(
task_id=task_id,
reason=f"Agent 请求重试整理历史 #{history_id}",
requested_by=f"agent:{user_id or 'unknown'}",
)
class DeleteTransferHistoryTool(MoviePilotTool):
name: str = "delete_transfer_history"
tags: list[str] = [
ToolTag.Write,
ToolTag.Transfer,
ToolTag.Admin,
]
description: str = (
"Request a safe retry for durable transfer history, or delete a legacy transfer history record by its ID. "
"Durable records keep their files and history and are retried only by the persistent scheduler. For legacy "
"non-successful-move records, the tool removes the old destination before deleting the history. If a durable "
"retry is accepted or rejected, stop and report that result; do not call transfer_file for the same record."
)
args_schema: Type[BaseModel] = DeleteTransferHistoryInput
require_admin: bool = True
def get_tool_message(self, **kwargs) -> Optional[str]:
"""根据参数生成友好的提示消息"""
history_id = kwargs.get("history_id")
return f"删除整理历史记录: ID={history_id}"
async def run(self, history_id: int, **kwargs) -> str:
logger.info(f"执行工具: {self.name}, 参数: history_id={history_id}")
try:
transferhis = get_agent_transfer_history_port()
history = await transferhis.async_get(history_id)
if not history:
return f"错误:整理历史记录不存在,ID={history_id}"
task_id = getattr(history, "transfer_task_id", None)
if task_id:
retry = await self.run_blocking(
"db",
_request_transfer_retry,
history_id=history_id,
task_id=task_id,
user_id=self._user_id,
)
outcome = "已登记" if retry.accepted else "未登记"
return (
f"durable 整理任务{outcome}重试:ID={history_id}"
f"task_id={task_id}state={retry.state.value}{retry.message}。"
"已保留目标文件、历史记录和失败计数;不要调用 transfer_file。"
)
title = history.title or "未知"
src = history.src or "未知"
status = "成功" if history.status else "失败"
deleted_dest = False
if history.dest_fileitem and not (history.status and history.mode == "move"):
dest_fileitem = FileItem(**history.dest_fileitem)
try:
destination_exists, destination_deleted = await self.run_blocking(
"storage",
_delete_history_destination_file,
dest_fileitem,
)
except asyncio.CancelledError:
logger.warning(
"删除整理历史的旧媒体文件等待已取消,底层文件操作可能仍在继续,"
"请确认实际状态后再重试,历史记录尚未删除,path=%s",
dest_fileitem.path,
)
raise
if destination_exists:
if not destination_deleted:
return f"错误:旧媒体库文件删除失败,路径={dest_fileitem.path}"
deleted_dest = True
await transferhis.async_delete(history_id)
message = (
f"已删除整理历史记录:ID={history_id},标题={title},源路径={src},状态={status}"
)
if deleted_dest:
message += ",已删除旧媒体库文件"
return message
except Exception as e:
logger.error(f"删除整理历史记录失败: {e}", exc_info=True)
return f"删除整理历史记录时发生错误: {str(e)}"