diff --git a/core/agent_builder.py b/core/agent_builder.py index d47f7d5..49efc75 100644 --- a/core/agent_builder.py +++ b/core/agent_builder.py @@ -59,6 +59,14 @@ _MEDIA_READDOC_SEG = """\ - `read_document` —— 读 PDF(豆包 Seed 2.0 Lite 文档理解),**专治扫描件**:markitdown 对某 PDF 转出**空 / 近空**(纯图页无文本层)→ 用它逐页 OCR 成 markdown。每页约 1-2 厘钱,单次上限 100 页(更长先拆分卷)。 - **多页整本 OCR 必传 `save_md`**(如 `save_md='source/xxx.md'`):全文落文件、只返回预览,后续直接 read 那个 md;只问局部内容("第3章指标是什么")传 `question` 即可不落盘。 - **何时不调**:PDF 有文本层且 markitdown 已转出正文(直接用那份 md,别重复花钱);DOCX/PPTX/XLSX(走 markitdown);单张图片(走 look_at_image)。""" + +# PDF 摄取是跨 skill 的基础入口,始终注入,不能依赖 agent 是否正确加载 paper / proposal。 +# read_document 只在配了 ARK 时挂载;没挂时扫描件明确停在“需 OCR”,不诱导现场装包或 +# 自造平行解析链路。正向写唯一入口,与 AGENTS.md 的 prompt 设计约定一致。 +_PDF_INGEST_SEG = """\ +## 读取已有 PDF +- **唯一入口**:先用 `markitdown` CLI 把 PDF 转成 task_dir 内的 Markdown 文件,再用 `read` 分段读取该 Markdown;文本型 PDF 到此即完成。 +- 若转换结果为空 / 近空,按扫描件处理:本轮有 `read_document` 时调用它并用 `save_md` 落 Markdown;没有该工具时,明确说明当前缺少扫描件 OCR 能力并请用户换可检索版本。依赖与解析器由平台镜像统一提供,任务内只走上述入口。""" _MEDIA_SEEDREAM_SEG = """\ - `seedream` —— 豆包图像生成 / 改图。产物自动落 `/figures/`。每次 **¥0.22**(联网 `search=true` 加 ¥0.05)。 - **文生图**(不传 `reference_images`):从零按 prompt 画。**改图 i2i**(传 `reference_images=["figures/xxx.png"]`):在已有图上做像素级修改。**用户对刚生成 / 上传的图说"改成 X / 换个颜色 / 去掉某处" → 必须走改图(reference_images 指那张图),绝不重新文生图**(重画 = 完全不同的图,丢原构图)。v1 改图仅支持单张参考。 @@ -359,6 +367,7 @@ def _build_system_prompt( user_root(workspace_dir, user_id) / ".kb" ) prompt += kb_block(workspace_dir, user_id, kb_dir_display) + prompt += "\n\n" + _PDF_INGEST_SEG if media_block: prompt += "\n\n" + media_block wd_abs = working_dir.resolve() diff --git a/tests/test_run_python_script_path.py b/tests/test_run_python_script_path.py index 4e69801..7c25c72 100644 --- a/tests/test_run_python_script_path.py +++ b/tests/test_run_python_script_path.py @@ -6,6 +6,11 @@ from tools.run_python import RunPythonTool class RunPythonScriptPathTests(unittest.TestCase): + def test_description_only_lists_preinstalled_libraries(self) -> None: + self.assertIn("Preinstalled libs include", RunPythonTool.description) + self.assertNotIn("install with shell pip", RunPythonTool.description) + self.assertNotIn("pypdf", RunPythonTool.description.lower()) + def test_executes_existing_script_path(self) -> None: with tempfile.TemporaryDirectory() as tmp: script = Path(tmp) / "hello.py" diff --git a/tests/test_system_prompt_paths.py b/tests/test_system_prompt_paths.py index 8cb443e..b6fe379 100644 --- a/tests/test_system_prompt_paths.py +++ b/tests/test_system_prompt_paths.py @@ -84,6 +84,16 @@ class TestSystemPromptPaths(unittest.TestCase): self.assertIn("`office_to_pdf`", prompt) self.assertIn("LibreOffice 在 backend host", prompt) + def test_existing_pdf_has_one_platform_ingest_route(self): + prompt, _, _ = _build("docker") + self.assertIn("## 读取已有 PDF", prompt) + self.assertIn("**唯一入口**", prompt) + self.assertIn("先用 `markitdown` CLI", prompt) + self.assertIn("转换结果为空 / 近空", prompt) + self.assertIn("本轮有 `read_document` 时调用它", prompt) + self.assertIn("依赖与解析器由平台镜像统一提供", prompt) + self.assertNotIn("pypdf", prompt.lower()) + def test_web_search_schema_reinforces_time_rules(self): from tools.web_search import WebSearchTool diff --git a/tools/run_python.py b/tools/run_python.py index 3adb8d3..b95843d 100644 --- a/tools/run_python.py +++ b/tools/run_python.py @@ -38,8 +38,8 @@ class RunPythonTool(Tool): "matplotlib charts, or any task where Python is more natural than chaining tools.\n" "Working directory is the agent's base dir (task_dir); relative paths resolve against it. " "Keep process scripts in scripts/; write deliverables to task_dir root or the SKILL-specified path.\n" - "Available libs (install with shell pip if missing): " - "pandas, numpy, matplotlib, python-pptx, python-docx, requests, pypdf." + "Preinstalled libs include: " + "pandas, numpy, matplotlib, python-pptx, python-docx, requests." ) parameters = { "type": "object",