客户端中途断开流时 Cython 协程 __Pyx_Coroutine_SendEx 断言 abort 整个 BFF。 证据链:3.2.8 崩 db.c / 3.3.0 仍崩(升级无效) / db 明文后迁移 sse_relay.c, 证明取消链上任意 Cython 协程均可触发。最终把 db.py/qa.py/sse_relay.py 加入编译白名单(明文),隔离实例断流探针 10/10 存活,生产同构建实测通过。 代价:3 模块失去编译硬化(无凭据内容),编译模块 30->27。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
5.4 KiB
任务书:开发 agent-3 —— P3 前端 UI(自然触发 + 文档 TAB + 能力徽标 + 右栏可拖宽)
前置必读
- docs/docgen_team_context.md(服务器环境事实 + 团队纪律,全部遵守)
- 本任务书;改任何文件前先读其全文,理解现有结构再动
职责范围(只改这些文件,不越界)
A. 新增 ui/src/api/docgen.js —— uploadLibrary/generate/getArtifactContent/saveArtifactContent/editArtifact/exportArtifact/listLibrary/downloadUrl(复用现有 http.js 封装,600s 兜底) B. 新增 ui/src/i18n/docgen.js —— 全部新文案(含能力徽标「文档生成」) C. 新增 ui/src/intent.js —— 前端意图路由 route(text, hasAttachments, hasActiveArtifact)->qa|docgen|edit|export。规则词典与后端 services/docgen/intent.py 完全一致(同一词典表、同一优先级:导出词→编辑词+有活动文档→写文档意图(写类动词+文档类型词+量词)→附件+写类动词→qa;漏判安全)。导出文档类型词词典与后端一致:论文/报告/通知/通告/公告/请示/批复/函/申请书/申报书/标书/合同/协议/方案/计划/总结/汇报/讲话稿/致辞/证明/纪要/简报/材料/说明书/指南 D. 新增 ui/src/stores/docgen.js —— 文档 TAB 状态:活动 artifact、md 内容、编辑态、导出态、模版检索候选;不 import bench.js 的状态(只调 setActiveTab) E. 修改 ui/src/components/chat/Composer.vue —— 拖拽区:dragover 高亮 → drop 收集(前端预检 20MB/5 个)→ 先调 uploadLibrary(入库主向量库,持久可用)→ chips(可移除,移除仅从本次引用拿掉);发送时按 intent.js 路由:docgen → chat.sendDocgen;QA → 原路径(附件注记进消息文本)。send() 现有逻辑零改动,docgen 走独立分支 F. 修改 ui/src/stores/chat.js —— 新增 sendDocgen(description, libraryIds):用户消息落库(走现有消息落库机制)→ 助手骨架(kind:docgen,pipeline 块带 capabilities:[{key:doc_writer, label:文档生成}] 徽标,steps 五步:解析资料/检索模版/规划大纲/逐节生成/导出文档,phase 复用 PHASE_COLOR_VAR 键 planning/retrieval/evidence/generation/done)→ generate(600s)→ 成功:blocks=[pipeline(done), artifact 块] + 持久化 + 自动切 bench.setActiveTab(doc);失败 _errorMarker。QA 路径的 pipeline 块注入本次实际启用的会话能力 chips(联网搜索/答案润色/Superpowers,label 取自 settings store 已加载 manifest)。现有 send/_runStream 零改动 G. 修改 ui/src/components/chat/PipelineCard.vue —— pc-head 加 capabilities 徽标区(v-for 渲染 chip,复用现有 badge 视觉),block.capabilities 缺省时零渲染(既有消息无影响) H. 新增 ui/src/components/chat/DocCard.vue —— 消息流内文档卡片:标题/模版名/「打开预览」按钮(切到文档 TAB) I. 新增 ui/src/components/bench/DocPane.vue —— 第 5 TAB 主体:markdown-it 渲染 HTML 预览(复用现有 markdown.js 渲染+消毒);块级就地编辑(标题/正文/列表/表格行 contenteditable,blur 序列化回 md + debounce PATCH 保存);「用 prompt 修改」输入行(调 edit 端点);「导出」按钮组(PDF/DOCX) J. 修改 ui/src/components/bench/BenchPanel.vue —— tabs 数组加 {key:doc, label:文档} + pane 链加 v-else-if 挂 DocPane(两处模板改动,无逻辑改动) K. 修改 ui/src/components/chat/AssistantMessage.vue —— 块渲染加 artifact 分支 L. 修改 ui/src/components/layout/AppShell.vue + ui/src/styles/base.css —— 右栏可拖拽改宽 + 手柄仿左栏:① .bench-wrap 左边缘加 .bench-resizer(宽 8px、cursor:col-resize,mousedown 拖动实时改宽,min 300px / max 60vw,mouseup 持久化 localStorage pa-bench-width,初始 380px,折叠态不拖拽);② 展开/收起按钮改成左栏 .side-handle-btn 同款:26×26 圆角、hairline 描边、surface-1 底、跨右栏左边缘半嵌(left:0 + translate(-50%,-50%))、垂直居中、图标 13px;③ 箭头方向镜像左栏:折叠态朝左(指向内容侧)、展开态朝右;④ 折叠态 28px 竖条保留为点击区,按钮嵌其上(同款式);⑤ 宽度变化与手柄位置联动(transition 0.3s 同左栏)
零改动红线
ui/src/stores/modes.js、ui/src/i18n/labels.js、ui/src/stores/bench.js(store)、ui/src/api/qa.js、ui/src/sse/parser.js
【纪律再强调】
- 不碰生产运行中的服务(8090/8091/5180 等);不自行重启 vite、不自行构建 dist
- 只动本任务书列出的文件;发现需要改其他文件 → 记入报告交 TL 裁决
- 不 commit、不 push、不 touch 部署树
【自测要求】
- 前端自测:cd ui && npx vitest run(如仓库已有前端测试惯例则照做;intent.js 必须有单元测试——与后端同用例表 20-30 条);无测试框架先例则至少 node --input-type=module 直接 import intent.js 跑断言脚本(intent.js 保持纯函数无 Vue 依赖以便 node 直测)
- 自测结果写入 docs/team/report_dev3.md(完成模块清单、测试通过数、已知限制)
【完成标准】
最终回复中明确写「DEV3 P3 完成」+ 报告路径 docs/team/report_dev3.md + 自测通过数
【重要补充】意图路由的规范词典与 30 条用例表已冻结于 docs/team/cases_intent.md(唯一事实源)——intent 实现与测试一律以它为准,不得自造词典/自造用例。