from __future__ import annotations import logging from collections.abc import Iterable from review_agent.models import FileAttachment from ..services.attachment_reader import read_attachment_details from .base import BaseSkill, SkillResult, WorkflowContext logger = logging.getLogger("review_agent.file_summary.skills.attachment_reader") class AttachmentReaderSkill(BaseSkill): name = "attachment_reader" def run(self, context: WorkflowContext) -> SkillResult: attachments = FileAttachment.objects.filter( conversation=context.batch.conversation, is_active=True, ).exclude(upload_status=FileAttachment.UploadStatus.DELETED) return self.run_for_attachments(attachments) def run_for_attachments(self, attachments: Iterable[FileAttachment]) -> SkillResult: attachment_list = list(attachments) logger.info( "Attachment reader skill started", extra={ "attachment_count": len(attachment_list), "attachment_ids": [attachment.pk for attachment in attachment_list], }, ) results = [read_attachment_details(attachment).to_dict() for attachment in attachment_list] if not results: logger.warning("Attachment reader skill found no attachments") return SkillResult(success=False, message="当前对话没有可读取的附件。") has_success = any(item["status"] == "success" for item in results) logger.info( "Attachment reader skill finished", extra={ "success": has_success, "success_count": sum(1 for item in results if item["status"] == "success"), "failed_count": sum(1 for item in results if item["status"] != "success"), }, ) return SkillResult( success=has_success, data={"attachments": results}, message="附件解析完成。" if has_success else "附件解析失败。", )