Conversation
参考 learn-claude-code (s01-s12) 体系重构 Agent 基础设施。 Phase 1 - Agent Loop + 工具层: - packages/agent_core/loop.py: 显式 AgentLoop 类,while + stop_reason 循环 - packages/agent_core/dispatcher.py: ToolDispatcher,工具注册表 + dispatch map - packages/agent_core/tools/: bash / filesystem handlers Phase 2 - 持久化 + Context: - packages/agent_core/tasks.py: TaskManager,JSON 文件持久化 + blockedBy 依赖图 - packages/agent_core/background.py: BackgroundTaskRunner,daemon 线程池 Phase 3 - Team 协作: - packages/agent_core/message_bus.py: MessageBus,JSONL 邮箱异步通信 - packages/agent_core/teammates.py: TeammateManager,持久 agent 线程管理 - packages/agent_core/protocols.py: TeamProtocols,shutdown/plan_approval FSM Skills (packages/agent_core/skills/): - agent-loop: AgentLoop 使用指南 - tool-dispatcher: 工具注册机制 - task-persistence: TaskManager 文件格式 - context-compaction: 3层压缩策略 - agent-teams: 多 agent 协作 - team-protocols: 通信协议 FSM README 引用 learn-claude-code 项目致谢。
- 添加 StreamingAgentLoop: 支持流式 LLM + SSE + 确认机制 - 添加 ConfirmationMixin: 接管 _CONFIRM_TOOLS pending 逻辑 - 添加 StreamingToolDispatcher: 适配生成器式 tool handlers - 添加 GlobalTrackerAdapter: global_tracker 兼容层 - 重构 agent_service.py: 使用新架构,保持原有接口不变 - 所有文件通过 py_compile 和 ruff check
- Context Compact (s06): 3层压缩策略,支持无限长度会话 - Layer1: 消息摘要 (LLM生成) - Layer2: 关键决策提取 - Layer3: 元信息压缩 - CompactingStreamingAgentLoop 混入类 - TodoWrite (s03): 统一任务计划接口 - TodoManager: JSON持久化,支持层级结构(parent_id) - PlannerMixin: 计划生成混入类 - 格式规范: [WHERE] [HOW] to [WHY] — expect [RESULT] - Subagents (s04): 增强型子Agent并行调度 - SubagentRunner: 独立线程执行,支持sync/async - SubagentPool: 并发控制(max_concurrent) - 全局单例 get_subagent_pool() - agent_service.py: 导出所有新模块供consumer使用 - 所有文件通过 py_compile 和 ruff check
修复的问题: 1. tool消息丢失:每个tool_result事件立即保存到DB 2. 消息累积逻辑错误:现在保存所有user/assistant/tool消息 3. SSE正则bug:修复 (.+?) DOTALL模式下可能匹配异常 4. 历史消息恢复:API层从DB加载消息传给stream_chat 5. stream_chat返回类型:改为 tuple[Iterator, conversation] 6. schemas: AgentMessage添加meta字段支持 涉及的变更: - agent.py: 重写消息保存逻辑,修复SSE解析 - agent_service.py: stream_chat/confirm_action/reject_action返回conversation - schemas.py: AgentMessage.meta字段
在 session_scope 外部访问 PipelineRun ORM 对象导致 DetachedInstanceError。 将 recent_runs 列表推导式移到 with scope 内部,确保对象 attached 时访问属性。
问题原因: - agent_core.loop.PaperMindToolResult 和 agent_tools.ToolResult 是两个同名不同模块的类 - _execute_and_emit/execute_confirmed_action/execute_and_continue 中的 isinstance 检查只匹配 PaperMindToolResult - execute_tool_stream 返回的是 agent_tools.ToolResult,导致 isinstance 返回 False - 结果:result 一直是默认值 "无结果",工具看起来"调用失败" 修复方案: - 增加 hasattr duck-typing 检查,兼容两种 ToolResult 类
- 新增后端数据模型: UserSchema, SensemakingSession, SchemaPaperInteraction
- 新增 Sensemaking API: Act1/2/3 认知重构流程端点
- 新增翻译 API: 划词翻译和段落对照翻译
- 新增论文分段 API: /papers/{id}/segments
- ToolPanel 重构: Tab 化 (翻译/AI聚合/Canvas)
- CanvasPanel: 完整的 Act1/2/3 引导流程 UI
- TranslationPanel: 划词翻译 + 全文对照模式
- PdfReader 集成 ToolPanel 替换旧 AI Panel
- main.py: 注册 sensemaking 和 translate 路由
- papers.py: 新增 /papers/{id}/segments 论文分段 API
- PdfReader.tsx: 集成 ToolPanel 组件
- config.py: 修复 ieee_api_key 缺失问题
- storage/models.py: 添加 UserSchema/SensemakingSession/SchemaPaperInteraction 表
- 左半屏显示原文 PDF - 右半屏固定显示 ToolPanel (翻译/AI聚合/Canvas) - 移除浮窗切换按钮 - 进度条自适应左半屏宽度
- 检测到 PDF 未下载时显示下载按钮 - 用户可直接在面板内下载 PDF - 改进错误提示
- 添加 paperPdfPath 属性 - 优先使用本地 PDF,其次 arXiv 在线代理 - PaperDetail 传入 pdf_path
- TranslationPanel 重构为左右分栏:左侧 PDF 原文,右侧翻译对照 - PdfReader 传递 paperArxivId 和 paperPdfPath 给 TranslationPanel - 清理未使用的状态变量(pdfDoc, currentPage, pageInput, goToPage)
- PyMuPDF 逐页提取文本,跟踪每段所属页码 - 每个分段 now includes pageNumber (1-indexed) - 为前端双语对照滚动同步提供基础
- PDF 滚动时自动滚动翻译面板到对应页码段落 - 翻译段落添加点击跳转功能,点击跳转到 PDF 对应页面 - 移除双向滚动同步(干扰页码同步逻辑) - 清理未使用的变量和多余注释
后端实现: - translate.py: 新增 extract_segments_from_pdf() 快速提取分段 - translate.py: 并发翻译控制(ThreadPoolExecutor, max_workers=5) - routers/translate.py: 新增 /bilingual-pdf 端点,支持两种模式 - fast: PyMuPDF 分段 + 并发翻译(1-2 分钟) - layout: PDFMathTranslate 布局保留(3-5 分钟) - 异步任务处理,不阻塞请求
- TranslationPanel 新增翻译模式下拉框 - 快速翻译:⚡ 1-2 分钟,文本对照 - 布局保留:📐 3-5 分钟,完整排版 - 仅在全屏对照模式显示模式选择
- 添加混合翻译模式说明 - 快速翻译:PyMuPDF 分段 + 并发(1-2 分钟) - 布局保留:PDFMathTranslate 完整排版(3-5 分钟)
模型配置更新: - config.py: 默认模型统一为 glm-4.7 / glm-4.6v - model_tier.py: 预设模板只保留智谱 GLM-4.7 系列 - LLMSettings.tsx: 前端预设只保留统一配置 配置说明: - 粗读/简单任务:glm-4.7 - 精读/复杂任务:glm-4.7 - 视觉任务:glm-4.6v - 降级备用:glm-4.7 简化模型管理,避免配置混乱。
界面改进: - 顶部添加当前激活配置概览卡片,一目了然 - 配置列表卡片样式优化,图标 + 模型标签更直观 - 表单分组展示(基础信息 / 模型配置),层次清晰 - 预设配置卡片带图标和描述,更有引导性 - 整体布局更紧凑、更专业 交互优化: - 文本模型输入联动(修改一个自动填其他) - 悬停效果和过渡动画 - 删除按钮仅在非激活状态可点击
- 删除旧的独立LLMSettings对话框页面 - 新Settings页面采用左侧导航+右侧内容布局 - 四个设置标签页:LLM配置/邮箱报告/Pipeline/运维 - 修复form label关联和button type等lint问题 - 路由/settings现在指向新的Settings组件
- 移除 showSettings state 和 SettingsDialog 弹窗 - 点击侧边栏设置改为导航到 /settings 路由 - 删除 SettingsDialog.tsx 组件 - 清理不再使用的 lazy/Suspense 导入 - 修复 Settings.tsx 中 useLocation 未定义错误
LLMTab: - 添加ProviderBadge彩色服务商标签 - 添加deactivate切回默认配置功能 - 添加OpenAI/Anthropic预设配置 EmailTab: - 添加send_email_report开关 - 添加recipient_emails收件人配置 - 添加cron_expression定时任务配置 - 添加include_paper_details/include_graph_insights选项 - 添加AddEmailConfigModal/EditEmailConfigModal完整表单 - 添加QQ邮箱/Gmail/163邮箱快捷预设 - 添加test邮件功能 PipelineTab: - 添加StatusDot状态指示器 - 添加paper_id显示 - 添加running/pending状态过滤 OpsTab: - 添加dailyJob每日任务 - 添加weeklyJob每周图维护 - 添加loading状态管理
- EmailTab: 添加 auto_deep_read 自动精读开关 - EmailTab: 添加 deep_read_limit 每日精读上限配置 - LLMTab: 添加 handleActivate/handleDelete 专用处理函数 - LLMTab: activate/delete/编辑按钮在操作中禁用防止竞态
- 新增"多源搜索"tab,支持 ArXiv/OpenAlex/Semantic Scholar 等多渠道 - 添加 paperApi.multiSourceSearch() 和 suggestChannels() API - 添加 MultiSourceSearchResult 和 ChannelSuggestion 类型 - 多源搜索区域包含:搜索框、渠道推荐、渠道选择按钮组 - 搜索结果展示论文标题、作者、来源和日期
P0 修复: - api.ts: 端点从 /papers/multi-source-search 改为 /papers/search-multi - api.ts: 修复响应字段映射 (papers→results, channel_stats→channelStats) - 类型定义: 更新 MultiSourcePaper 匹配后端返回结构 - arxiv_channel.py: 确保 source/source_id 正确设置 P1 修复: - arxiv_channel.py: days_back=0 移除默认7天限制 - ChannelContext.tsx: 使用 resolveApiBase() 替代硬编码 /api - AggregationPanel.tsx: 使用 paperApi.multiSourceSearch() 替代原生 fetch - MultiSourceSearchBar.tsx: 使用 paperApi.suggestChannels() 替代原生 fetch
从一次真实使用记录定位到全链路多处核心 bug,本次一并修复: 后端 - arXiv 检索: - arxiv_client.py 补 import time(重试分支原本会 NameError) - fetch_latest 默认 days_back=0(原 7 天过滤把 OpenShape/Uni3D 等经典论文全筛掉) - _build_arxiv_query 拆词上限 3→6,新增带引号精确短语搜索 - /ingest/arxiv 路由暴露 days_back 参数(默认 0),前端 ingestApi.arxiv 同步 - search_arxiv Agent 工具暴露 days_back / sort_by(默认 relevance) 后端 - Agent 状态机: - 新增 _HANDLED_ACTION_CACHE TTL 内存缓存,confirm/reject 幂等保护 - 找不到 action 时区分文案:「已处理过」vs「真的过期」,消除矛盾提示 - SYSTEM_PROMPT 强化:ingest_arxiv 前必须列出候选标题/作者/年份,禁止盲 ID 确认 前端 - 错误处理: - services/api.ts 新增 friendlyStatusMessage + extractErrorMessage - request/fetchSSE 响应非 JSON 或以 < / <!doctype 开头一律按状态码降级文案 - 504/524/408/502/503 等全部有对应中文提示,Cloudflare HTML 错误页不再甩用户 - errorHandler.ts 补 504/524/408 识别 + HTML 污染兜底 前端 - Agent 交互: - AgentSessionContext 新增 handledActionsRef,防双击/StrictMode 重复提交 - ActionConfirmCard 特化 ingest_arxiv:反查 search_arxiv 候选,显示标题+作者卡片 顺带修复: - PaperDetail.tsx 精读结果错塞到 savedDeep(真 bug,导致精读后空白) - AggregationPanel/Collect 多源搜索类型不匹配(sources vs source 字段) - 清理 agent_tools.py 的 Iterator TYPE_CHECKING / set comprehension / 重复字典 key - 清理 Collect 及 PaperDetail 多处 unused import Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
🔍 OpenCode PR Review Required这是一个受保护的分支,merge 前需要进行 code review。 请运行以下命令进行 OpenCode review: 或者在 PR 页面评论 This is an automated reminder from PR Review Gate. |
|
/oc review |
|
Good! The TypeScript deprecation warning is not a real error. Now let me provide my review: Code Review Summary这是一个高质量的 bug fix PR,修复了从真实使用中发现的 11 个核心问题。以下是详细评审: ✅ 主要修复1. arXiv 检索问题 (
|
| 问题 | 修复前 | 修复后 | 证据 |
|---|---|---|---|
| OpenShape 检索 | 0 篇 | 2 篇 | 2305.10764 NeurIPS'23 |
| Uni3D 检索 | 0 篇 | 5 篇 | 2310.06773 ICLR'24 |
| Cloudflare 504 | 甩 HTML 页 | 中文提示 | friendlyStatusMessage |
| 重复 confirm | "已过期"矛盾 | "已处理过" | _HANDLED_ACTION_CACHE |
📝 建议
- 高优先级: 修复
agent_tools.py:1017嵌套线程池问题(性能优化) - 中优先级: 清理
arxiv_client.py重复的 cs.CL 分类 - 低优先级: 考虑为
_HANDLED_ACTION_CACHE添加线程锁(可选)
✅ Review 结论: LGTM (Look Good To Merge)
核心 bug 修复到位,错误处理健壮,端到端验证充分。建议合并后人肉过一遍前端 UX(504 降级/入库卡片/精读显示)。
回应 PR #17 opencode review 建议(中优先级): fetch_categories 的 fallback 列表里 cs.CL 被错写了两次 (Computation and Language / Computational Linguistics), 官方 arxiv 分类只有一个 cs.CL = Computation and Language,删除重复项。 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
🔍 OpenCode PR Review Required这是一个受保护的分支,merge 前需要进行 code review。 请运行以下命令进行 OpenCode review: 或者在 PR 页面评论 This is an automated reminder from PR Review Gate. |
|
感谢 review!逐条回应: ✅ 已处理
⏸ 保留现状(带理由)[高优] [低优] 合并前再本地跑了一次 smoke 确认删分类没破坏 |

Summary
从一次真实使用记录定位到全链路多处核心 bug,本次一并修复:arXiv 搜不到经典论文、入库状态机「成功+过期」矛盾、Cloudflare 504 HTML 甩用户脸上、入库前看不到论文标题等。11 个文件,+364/-112。
问题与修复
后端 - arXiv 检索
arxiv_client.py补import time(重试分支原本会 NameError 崩)fetch_latest默认days_back=0—— 原 7 天过滤把 OpenShape/Uni3D/PointContrast 等经典论文全筛掉_build_arxiv_query拆词上限 3→6;新增引号精确短语搜索/ingest/arxiv路由暴露days_back参数(默认 0),前端ingestApi.arxiv同步search_arxivAgent 工具暴露days_back/sort_by(默认 relevance)后端 - Agent 状态机
_HANDLED_ACTION_CACHE(TTL 1h 内存缓存)做 confirm/reject 幂等保护SYSTEM_PROMPT强化:ingest_arxiv 前必须列出候选标题/作者/年份,禁止盲 ID 确认前端 - 错误处理
services/api.ts新增friendlyStatusMessage+extractErrorMessagerequest/fetchSSE响应非 JSON 或以</<!doctype开头一律按状态码降级文案errorHandler.ts补 504/524/408 识别 + HTML 污染兜底前端 - Agent 交互
AgentSessionContext新增handledActionsRef,防双击/StrictMode 重复提交ActionConfirmCard特化ingest_arxiv:反查search_arxiv候选,显示标题+作者卡片顺带修复
PaperDetail.tsx精读结果错塞savedDeep(真 bug,导致精读后界面空白)AggregationPanel/Collect多源搜索字段不匹配(sourcesvssource)agent_tools.pyIterator TYPE_CHECKING / set comprehension / 重复字典 key真实端到端验证
2305.10764OpenShape (NeurIPS'23)2310.06773Uni3D (ICLR'24)2305.08275ULIP-2 原版2007.10985PointContrast 原版2203.06604Point-MAE1512.03012ShapeNet 经典原版Test plan
npx tsc --noEmit前端 0 错误npx vite build生产构建通过(2.5s)python -m py_compile后端 3 个改动文件通过/ingest/arxiv?query=X对 6 个经典查询全部命中🤖 Generated with Claude Code