From 38790e21478c99a7b85ec8def6b7bd82a7b879da Mon Sep 17 00:00:00 2001 From: Color2333 <1552429809@qq.com> Date: Mon, 20 Jul 2026 03:37:09 +0800 Subject: [PATCH] =?UTF-8?q?fix(tools):=20search.py=20=E7=9F=AD=E5=89=8D?= =?UTF-8?q?=E7=BC=80=20paper=5Fid=20=E5=AF=BC=E8=87=B4=20get=5Fpaper=5Fdet?= =?UTF-8?q?ail/get=5Fsimilar/citation=5Ftree=20=E5=B4=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR #60 修了 read/figures/reasoning,但 search.py 仍有同样 bug: - _get_paper_detail: line 53 用 UUID(paper_id) 重新查(既多余又崩短前缀), 且 line 49 已调 _require_paper 拿到完整论文对象,直接用即可 - _get_similar_papers: line 78 UUID(paper_id) 崩;line 107 返回原始短前缀给 LLM - _get_citation_tree: line 181 传原始 paper_id 给 GraphService.citation_tree, 内部用 paper.id 作 dict key,短前缀不匹配 → root_paper 为 None 修复: - _get_paper_detail: 用 _require_paper 返回的 p 直接构造 data,删重复 UUID 查询 - _get_similar_papers: pid = UUID(paper.id);返回 paper.id 给 LLM - _get_citation_tree: 用 paper.id 传给 citation_tree 实测前:生产 b7e07388 → LLM 先调 get_paper_detail → "badly formed hexadecimal UUID", LLM 改调 search_papers(keyword=b7e07388) → 0 结果 → 放弃。 修复后:get_paper_detail 直接用 _require_paper 解析的完整论文,短前缀可用。 测试:69 passed / 2 skipped(无回归)。 --- packages/ai/tools/handlers/search.py | 50 +++++++++++++++------------- 1 file changed, 26 insertions(+), 24 deletions(-) diff --git a/packages/ai/tools/handlers/search.py b/packages/ai/tools/handlers/search.py index 4a64ad6..e097b1c 100644 --- a/packages/ai/tools/handlers/search.py +++ b/packages/ai/tools/handlers/search.py @@ -49,33 +49,34 @@ def _get_paper_detail(paper_id: str) -> ToolResult: p, err = _require_paper(paper_id) if err: return err - with session_scope() as session: - p = PaperRepository(session).get_by_id(UUID(paper_id)) - title = p.title or "" - data = { - "id": str(p.id), - "title": title, - "arxiv_id": p.arxiv_id, - "abstract": (p.abstract or "")[:1000], - "publication_date": str(p.publication_date) if p.publication_date else None, - "read_status": p.read_status.value, - "pdf_path": p.pdf_path, - "has_embedding": p.embedding is not None, - "categories": (p.metadata_json or {}).get("categories", []), - "authors": (p.metadata_json or {}).get("authors", []), - } - return ToolResult( - success=True, - data=data, - summary=f"论文: {title[:60]}" + ("..." if len(title) > 60 else ""), - ) + # p 已是 _require_paper 解析出的完整论文对象(detached 但属性已加载)。 + # 不再用 UUID(paper_id) 重新查——短前缀会崩,且重复查询无意义。 + title = p.title or "" + data = { + "id": str(p.id), + "title": title, + "arxiv_id": p.arxiv_id, + "abstract": (p.abstract or "")[:1000], + "publication_date": str(p.publication_date) if p.publication_date else None, + "read_status": p.read_status.value, + "pdf_path": p.pdf_path, + "has_embedding": p.embedding is not None, + "categories": (p.metadata_json or {}).get("categories", []), + "authors": (p.metadata_json or {}).get("authors", []), + } + return ToolResult( + success=True, + data=data, + summary=f"论文: {title[:60]}" + ("..." if len(title) > 60 else ""), + ) def _get_similar_papers(paper_id: str, top_k: int = 5) -> ToolResult: paper, err = _require_paper(paper_id) if err: return err - pid = UUID(paper_id) + # 用 paper.id(完整 UUID),不用原始短前缀调 UUID() + pid = UUID(paper.id) if not paper.embedding: return ToolResult( success=False, @@ -103,7 +104,7 @@ def _get_similar_papers(paper_id: str, top_k: int = 5) -> ToolResult: return ToolResult( success=True, data={ - "paper_id": paper_id, + "paper_id": paper.id, "similar_ids": [str(x) for x in ids], "items": items, }, @@ -173,11 +174,12 @@ def on_progress(msg: str) -> None: def _get_citation_tree(paper_id: str, depth: int = 2) -> ToolResult: - _, err = _require_paper(paper_id) + paper, err = _require_paper(paper_id) if err: return err try: - result = GraphService().citation_tree(root_paper_id=paper_id, depth=depth) + # 用完整 UUID(paper.id),不用原始短前缀(citation_tree 内部用 paper.id 作 dict key) + result = GraphService().citation_tree(root_paper_id=paper.id, depth=depth) node_count = len(result.get("nodes", [])) edge_count = len(result.get("edges", [])) return ToolResult(