feat(agent): 增加 LLM 路由与诊断日志

This commit is contained in:
2026-06-06 17:56:41 +08:00
parent 47b5ad1054
commit fa77c68d77
21 changed files with 832 additions and 17 deletions

View File

@@ -1,6 +1,7 @@
from __future__ import annotations
import csv
import logging
from dataclasses import asdict, dataclass, field
from pathlib import Path
@@ -15,6 +16,9 @@ MAX_PREVIEW_CHARS = 3000
MAX_ROWS_PER_SHEET = 20
logger = logging.getLogger("review_agent.file_summary.attachment_reader")
@dataclass(frozen=True)
class AttachmentReadResult:
status: str
@@ -32,10 +36,29 @@ class AttachmentReadResult:
def read_attachment_details(attachment: FileAttachment) -> AttachmentReadResult:
file_path = _attachment_absolute_path(attachment)
file_type = Path(attachment.original_name).suffix.lower().lstrip(".")
logger.info(
"Attachment read started",
extra={
"attachment_id": attachment.pk,
"conversation_id": attachment.conversation_id,
"original_name": attachment.original_name,
"file_type": file_type,
"storage_path": attachment.storage_path,
"resolved_path": str(file_path),
},
)
if not file_path.exists():
logger.warning(
"Attachment read missing file",
extra={"attachment_id": attachment.pk, "resolved_path": str(file_path)},
)
return _failed(attachment, file_type, "附件文件不存在。")
if file_type not in SUPPORTED_EXTENSIONS:
logger.warning(
"Attachment read unsupported type",
extra={"attachment_id": attachment.pk, "file_type": file_type},
)
return _failed(attachment, file_type, f"暂不支持解析 .{file_type or 'unknown'} 文件。", "unsupported")
try:
@@ -52,9 +75,21 @@ def read_attachment_details(attachment: FileAttachment) -> AttachmentReadResult:
else:
sections = _read_text(file_path)
except Exception as exc:
logger.exception(
"Attachment read failed",
extra={"attachment_id": attachment.pk, "file_type": file_type, "error": str(exc)},
)
return _failed(attachment, file_type, str(exc))
preview = _build_preview(sections)
logger.info(
"Attachment read finished",
extra={
"attachment_id": attachment.pk,
"section_count": len(sections),
"preview_length": len(preview),
},
)
return AttachmentReadResult(
status="success",
filename=attachment.original_name,

View File

@@ -1,5 +1,6 @@
from __future__ import annotations
import logging
from pathlib import Path
from django.conf import settings
@@ -8,6 +9,9 @@ from openpyxl import Workbook
from review_agent.models import ExportedSummaryFile, FileSummaryBatch
logger = logging.getLogger("review_agent.file_summary.export_excel")
def _exports_dir(batch: FileSummaryBatch) -> Path:
root = Path(batch.work_dir) if batch.work_dir else Path(settings.MEDIA_ROOT) / "file_summary" / batch.batch_no
export_dir = root / "exports"
@@ -16,6 +20,7 @@ def _exports_dir(batch: FileSummaryBatch) -> Path:
def generate_excel_export(batch: FileSummaryBatch) -> ExportedSummaryFile:
logger.info("Excel export generation started", extra={"batch_id": batch.pk})
workbook = Workbook()
summary = workbook.active
summary.title = "汇总信息"
@@ -47,9 +52,14 @@ def generate_excel_export(batch: FileSummaryBatch) -> ExportedSummaryFile:
path = _exports_dir(batch) / f"{batch.batch_no}-summary.xlsx"
workbook.save(path)
return ExportedSummaryFile.objects.create(
exported = ExportedSummaryFile.objects.create(
batch=batch,
export_type=ExportedSummaryFile.ExportType.EXCEL,
file_name=path.name,
storage_path=str(path),
)
logger.info(
"Excel export generation finished",
extra={"batch_id": batch.pk, "export_id": exported.pk, "path": str(path)},
)
return exported

View File

@@ -1,5 +1,6 @@
from __future__ import annotations
import logging
from pathlib import Path
from django.conf import settings
@@ -7,6 +8,9 @@ from django.conf import settings
from review_agent.models import ExportedSummaryFile, FileSummaryBatch
logger = logging.getLogger("review_agent.file_summary.report")
def _exports_dir(batch: FileSummaryBatch) -> Path:
root = Path(batch.work_dir) if batch.work_dir else Path(settings.MEDIA_ROOT) / "file_summary" / batch.batch_no
export_dir = root / "exports"
@@ -55,6 +59,7 @@ def build_markdown_report(batch: FileSummaryBatch) -> str:
def generate_markdown_report(batch: FileSummaryBatch) -> tuple[ExportedSummaryFile, str]:
logger.info("Markdown report generation started", extra={"batch_id": batch.pk})
content = build_markdown_report(batch)
path = _exports_dir(batch) / f"{batch.batch_no}-summary.md"
path.write_text(content, encoding="utf-8")
@@ -64,4 +69,8 @@ def generate_markdown_report(batch: FileSummaryBatch) -> tuple[ExportedSummaryFi
file_name=path.name,
storage_path=str(path),
)
logger.info(
"Markdown report generation finished",
extra={"batch_id": batch.pk, "export_id": exported.pk, "path": str(path)},
)
return exported, build_summary_table(batch)