Files
ai-ticket-platform/backend/apps/knowledge/tasks.py
2026-07-27 19:01:19 +08:00

154 lines
5.1 KiB
Python

from celery import shared_task
from django.contrib.auth import get_user_model
from apps.audit.models import OperationAuditLog
from apps.knowledge.documents import process_knowledge_document
from apps.knowledge.embeddings import KnowledgeEmbeddingError
from apps.knowledge.models import KnowledgeDocument
from apps.knowledge.services import sync_governed_asset_index, sync_ticket_search_index
@shared_task(
bind=True,
autoretry_for=(KnowledgeEmbeddingError,),
retry_backoff=True,
retry_jitter=True,
max_retries=3,
)
def sync_ticket_search_index_task(self, ticket_id: int) -> int:
return sync_ticket_search_index(ticket_id)
def dispatch_ticket_search_index(ticket_id: int) -> None:
try:
sync_ticket_search_index_task.delay(ticket_id)
except Exception:
OperationAuditLog.objects.create(
module="knowledge",
action="ticket_index_queue_failed",
target_type="ticket",
target_id=str(ticket_id),
request_snapshot={},
result="failure",
)
@shared_task(
bind=True,
autoretry_for=(KnowledgeEmbeddingError,),
retry_backoff=True,
retry_jitter=True,
max_retries=3,
)
def sync_governed_asset_index_task(
self,
asset_type: str,
object_id: int,
) -> int:
return sync_governed_asset_index(asset_type, object_id)
def dispatch_governed_asset_index(asset_type: str, object_id: int) -> None:
try:
sync_governed_asset_index_task.delay(asset_type, object_id)
except Exception:
OperationAuditLog.objects.create(
module="knowledge",
action="asset_index_queue_failed",
target_type=asset_type,
target_id=str(object_id),
request_snapshot={},
result="failure",
)
@shared_task(name="apps.knowledge.tasks.process_knowledge_document")
def process_knowledge_document_task(document_id: int) -> None:
process_knowledge_document(document_id)
def dispatch_knowledge_document_processing(document_id: int) -> None:
try:
result = process_knowledge_document_task.delay(document_id)
except Exception as error:
document = KnowledgeDocument.objects.filter(id=document_id).first()
if document is not None:
document.parse_status = "failed"
document.parse_error = "文档处理任务入队失败,请重试"
document.task_id = ""
document.save(
update_fields=["parse_status", "parse_error", "task_id", "updated_at"]
)
OperationAuditLog.objects.create(
module="knowledge",
action="document_processing_queue_failed",
target_type="knowledge_document",
target_id=str(document.public_id) if document else str(document_id),
request_snapshot={"error_type": type(error).__name__},
result="failed",
)
return
KnowledgeDocument.objects.filter(id=document_id).update(task_id=result.id or "")
@shared_task(name="apps.knowledge.tasks.start_ticket_knowledge_distillation")
def start_ticket_knowledge_distillation_task(
ticket_id: int,
actor_id: int | None = None,
) -> int | None:
from apps.knowledge.distillation import start_ticket_knowledge_distillation
from apps.tickets.models import Ticket
from apps.workitems.services import sync_knowledge_distillation_work_item
ticket = Ticket.objects.filter(id=ticket_id).first()
if ticket is None:
return None
actor = get_user_model().objects.filter(id=actor_id).first() if actor_id else None
try:
distillation = start_ticket_knowledge_distillation(ticket, created_by=actor)
except Exception as error:
OperationAuditLog.objects.create(
user=actor,
module="knowledge",
action="knowledge_distillation_start_failed",
target_type="ticket",
target_id=str(ticket_id),
request_snapshot={"error_type": type(error).__name__},
result="failed",
)
sync_knowledge_distillation_work_item(
ticket,
error_code="start_failed",
error_message=str(error),
actor=actor,
)
return None
return distillation.id
def dispatch_ticket_knowledge_distillation(
ticket_id: int,
actor_id: int | None = None,
) -> None:
try:
start_ticket_knowledge_distillation_task.delay(ticket_id, actor_id)
except Exception as error:
from apps.tickets.models import Ticket
from apps.workitems.services import sync_knowledge_distillation_work_item
OperationAuditLog.objects.create(
module="knowledge",
action="knowledge_distillation_queue_failed",
target_type="ticket",
target_id=str(ticket_id),
request_snapshot={"error_type": type(error).__name__},
result="failed",
)
ticket = Ticket.objects.filter(id=ticket_id).first()
if ticket is not None:
sync_knowledge_distillation_work_item(
ticket,
error_code="queue_failed",
error_message="知识蒸馏任务入队失败",
)