diff --git a/packages/ai/tools/handlers/figures.py b/packages/ai/tools/handlers/figures.py index 0bf3a3e..cd6da0c 100644 --- a/packages/ai/tools/handlers/figures.py +++ b/packages/ai/tools/handlers/figures.py @@ -6,8 +6,6 @@ from uuid import UUID from packages.ai.tools.types import ToolProgress, ToolResult -from packages.storage.db import session_scope -from packages.storage.repositories import PaperRepository if TYPE_CHECKING: from collections.abc import Iterator @@ -16,25 +14,25 @@ def _analyze_figures(paper_id: str, max_figures: int = 10) -> Iterator[ToolProgress | ToolResult]: """提取并解读论文图表""" from packages.ai.figure_service import FigureService + from packages.ai.tools.base import _require_paper - with session_scope() as session: - repo = PaperRepository(session) - try: - paper = repo.get_by_id(UUID(paper_id)) - except (ValueError, Exception) as exc: - yield ToolResult(success=False, summary=f"论文不存在: {exc}") - return - if not paper.pdf_path: - yield ToolResult(success=False, summary="论文没有 PDF 文件,无法提取图表") - return - pdf_path = paper.pdf_path - title = paper.title + # 用 _require_paper 统一解析(支持短前缀,返回 detached 但属性已加载的 paper) + paper, err = _require_paper(paper_id) + if err: + yield err + return + if not paper.pdf_path: + yield ToolResult(success=False, summary="论文没有 PDF 文件,无法提取图表") + return + pdf_path = paper.pdf_path + title = paper.title + pid = UUID(paper.id) # 用完整 UUID,不用原始短前缀 yield ToolProgress(message=f"正在提取「{(title or '')[:30]}」中的图表...", current=1, total=3) svc = FigureService() try: results = svc.analyze_paper_figures( - UUID(paper_id), + pid, pdf_path, max_figures=max_figures, ) diff --git a/packages/ai/tools/handlers/read.py b/packages/ai/tools/handlers/read.py index a3ed786..937475e 100644 --- a/packages/ai/tools/handlers/read.py +++ b/packages/ai/tools/handlers/read.py @@ -24,7 +24,9 @@ def _skim_paper(paper_id: str) -> Iterator[ToolProgress | ToolResult]: if not paper.abstract: yield ToolResult(success=False, summary="该论文缺少摘要,无法执行粗读") return - pid = UUID(paper_id) + # 用 paper.id(_require_paper 已 resolve 成完整 UUID),不用原始 paper_id + # (原始可能是短前缀,UUID(paper_id) 会崩 "badly formed hexadecimal UUID") + pid = UUID(paper.id) title = (paper.title or "")[:40] yield ToolProgress(message=f"正在粗读「{title}」...", current=1, total=2) try: @@ -48,7 +50,7 @@ def _deep_read_paper(paper_id: str) -> Iterator[ToolProgress | ToolResult]: if not paper.arxiv_id and not paper.pdf_path: yield ToolResult(success=False, summary="该论文无 arXiv ID 且无 PDF,无法精读") return - pid = UUID(paper_id) + pid = UUID(paper.id) title = (paper.title or "")[:40] yield ToolProgress(message=f"正在精读「{title}」,预计 30-60 秒...", current=1, total=3) try: @@ -68,11 +70,11 @@ def _embed_paper(paper_id: str) -> Iterator[ToolProgress | ToolResult]: if err: yield err return - pid = UUID(paper_id) + pid = UUID(paper.id) if paper.embedding: yield ToolResult( success=True, - data={"paper_id": paper_id, "status": "already_embedded"}, + data={"paper_id": paper.id, "status": "already_embedded"}, summary="该论文已有向量,跳过", ) return @@ -87,7 +89,7 @@ def _embed_paper(paper_id: str) -> Iterator[ToolProgress | ToolResult]: PaperPipelines().embed_paper(pid) yield ToolResult( success=True, - data={"paper_id": paper_id, "status": "embedded"}, + data={"paper_id": paper.id, "status": "embedded"}, summary="向量化完成", ) except Exception as exc: diff --git a/packages/ai/tools/handlers/reasoning.py b/packages/ai/tools/handlers/reasoning.py index ced908f..4cb7ee2 100644 --- a/packages/ai/tools/handlers/reasoning.py +++ b/packages/ai/tools/handlers/reasoning.py @@ -6,8 +6,6 @@ from uuid import UUID from packages.ai.tools.types import ToolProgress, ToolResult -from packages.storage.db import session_scope -from packages.storage.repositories import PaperRepository if TYPE_CHECKING: from collections.abc import Iterator @@ -16,20 +14,20 @@ def _reasoning_analysis(paper_id: str) -> Iterator[ToolProgress | ToolResult]: """推理链深度分析""" from packages.ai.reasoning_service import ReasoningService + from packages.ai.tools.base import _require_paper - with session_scope() as session: - repo = PaperRepository(session) - try: - paper = repo.get_by_id(UUID(paper_id)) - except (ValueError, Exception) as exc: - yield ToolResult(success=False, summary=f"论文不存在: {exc}") - return - title = paper.title + # 用 _require_paper 统一解析(支持短前缀,返回 detached 但属性已加载的 paper) + paper, err = _require_paper(paper_id) + if err: + yield err + return + title = paper.title + pid = UUID(paper.id) # 用完整 UUID,不用原始短前缀 yield ToolProgress(message=f"正在分析「{(title or '')[:30]}」的推理链...", current=1, total=2) svc = ReasoningService() try: - result = svc.analyze(UUID(paper_id)) + result = svc.analyze(pid) except Exception as exc: yield ToolResult(success=False, summary=f"推理链分析失败: {exc}") return