Commit Graph
20 Commits
Author SHA1 Message Date
LuminousRuoxi c2243a3200 feat(skill): 追加 F 类文书场景特化 tell,修正 P11/P04 映射
prodream essay-chat 那份裁剪版比 HVR 多出 5 条文书场景特化条目——罗列堆料、
匀速、换名、过度工整、模板过渡。它们在通用清单里不收(学术/媒体/技术写作
中都正常),放进申请文书才成为 tell,HVR 的 A–E 里没有对应位置。

处理:作为 F 节**追加**进现有分类,不替换 A–E(A–E 覆盖更全,且文末已解释
A–E 与 P01–P12 的关系)。同时补两类条目 + 误报警戒:§27/§29 正是用功的非
母语学生的典型写法,单独出现不报;§26/§30 升为「见一次就该动手」。

顺带修正文末映射表:P11 同义换写一直漏(↔ §28),P04 平行结构也漏(↔ §6);
「A–E 是你的判断框架」改为「A–F」。

证明:
- docs/_probe_skill_f_section_20260911.py:静态核对 skill 正文含 F 节 8/8 项
  (F 标题、§26–§30、误报警戒、删词不删意);真实 /api/chat/stream 跑两次,
  两次均逐字引原文报出 §26 名词堆砌,run2 另报 §27 句长均匀
- artifact: docs/_skill_f_probe_20260911.json(docs/ 已 gitignore)
- pytest:65 passed
2026-09-11 11:03:13 +08:00
LuminousRuoxi 76d3b30e7d feat: 问题点数量口径改为 单段 1–3 / 全篇 5–10
产品口径(2026-09-11):全篇 Pattern 由「最多 5 个」改为 5–10 个,单段主要
Pattern 由「最多 2 个」改为 1–3 个。依据 PRD §13.1(单段最多默认展示 1–3 个
主要 Pattern)与 §19.3(只概括当前段最主要的 1–3 类问题)。每段批注 3 条上限不变。

全篇 5–10 带下限,与「模型不得无 evidence 输出 Pattern」冲突——只有下限没有
逃生口,模型会编证据凑数。因此两处同时补上「证据优先于数量,下限不得靠编造
evidence 来凑」;SKILL.md 原有「也不要硬凑到十条」随口径一并改写。

无硬截断代码需要同步:evidence.sanitize_patterns 只过滤证据不截数量,前端
index.html:1053/1059 的 slice(0,3) 本就是单段 1–3 的展示上限。

证明 artifact(docs/ 被 gitignore,本地留存):
- docs/_probe_pattern_counts_20260911.py 真实链路探针
- docs/_pattern_counts_20260911_run1.json / _pattern_counts_20260911.json
- docs/Agent化改造方案_20260911.md §十 口径与实测记录

实测(同篇文书,gemini-3.7-flash via OpenRouter,走真实 /api/diagnose):
run1 patterns=5 批注 1/1/2/2 证据 11/11;run2 patterns=6 批注 1/1/3/2 证据 16/16。
两次均在区间内且非死咬下限,4 段 ai_focus 全非空,证据 100% 可逐字回溯。
单测 65 例全绿(test_demo.py 35 + test_agent.py 30)。
2026-09-11 10:41:22 +08:00
LuminousRuoxi bdc6a53f81 refactor: 删掉随 agent 化失效的 applyUnderstandingCorrection,原位留已知偏差说明
顾问纠正某段理解时,改造前它会同时改写该段的 semantic_anchor;现在走
record_advisor_note 只落成分段约束,锚点不跟着改。纠正内容仍会进诊断/复检的
paragraph_constraints,所以不是静默丢失,但与原行为有差——写在原函数位置而不是
只记在方案文档里,读代码的人能看见。
2026-09-11 10:26:04 +08:00
LuminousRuoxi 94a26227c1 feat: 对话层 Agent 化(对话底座 + 自研 skill)
把对话页从固定状态机换成 skill 驱动的 Agent:顾问说什么都原样发给 agent,
由 SKILL.md + 工具决定该聊还是该调工具。工作台(workbenchView)未改动。

后端
- llm.py:新增 stream_chat()(流式 + tools),并带 reasoning 端点自动降级
  (gemini-3.7-flash 拒绝 effort:none,首次 400 后锁定重试)
- agent.py:最小对话底座内核——skill 注入 + 工具循环 + SSE 事件
- tools.py:8 个工具包住既有能力(analyze/diagnose/scaffold/reference/
  translate/recheck/record_note/confirm),延迟 import main 复用已验证的
  endpoint 处理器与测试接缝,prompts.py/schemas.py/evidence.py 未改一行
- main.py:POST /api/chat/stream(SSE)

skill
- skills/hvr-rewrite/SKILL.md:分诊规则、首轮盘点、AI 味清单对齐
  blader/humanizer 的 A–E 分类(含强度校准与反误报)、诚实性硬约束

前端
- 流式正文 + 工具卡片 + 选项按钮;工具 payload 直接喂既有渲染函数
  (renderUnderstanding/renderDiagnosis/renderRecheck),没有第二套 UI
- 删除随 agent 化失效的 runDiagnose / applyUnderstandingCorrection 死代码

验证(真实模型,非 mock)
- 65 单测全绿(test_agent.py 30 + test_demo.py 35)
- 逐轮实跑:盘点 → 确认 → 诊断 → 复检,SSE 事件序列与 payload kind 均符合契约
- 前端 readSSE 用真实响应字节按 7/64/全量三种切块回放,事件序列一致
- 实测修掉两个只在真跑时暴露的问题:模型调完分析直接调确认工具导致正文为空
  (SKILL.md 补「正文先行」硬规则);伪标题 `**N. 标题**` 让列表判定失败、
  短横线漏成字面字符(前端改逐行分组渲染)

未验证:浏览器人工走查(无浏览器自动化环境),仅到「真实 HTTP + 真实字节回放」这一层。
2026-09-11 10:25:12 +08:00
LuminousRuoxi 493c7f6416 fix: 左栏打开时滚动条停在最下面(应默认在顶部)
- 根因: 浏览器刷新会恢复内层滚动容器的位置,且恢复时机可能晚于渲染;
  之前 renderOriginalPane 无条件沿用旧 scrollTop,打开即停在底部(用户实测)
- renderOriginalPane 加 keepScroll 参数:默认回顶部(首次渲染/切段/切视图),
  仅翻译与对照展开/收起保持位置(这两处是内容更新,沿用位置才不跳)
- 首次渲染后再延迟固定一次顶部,对抗浏览器延迟的滚动恢复
- 验证: 打开/刷新/切段/切聚焦全文 均回顶部,翻译保持位置;长内容 5/5 + 核心场景 5/6
  (1 项为测试内容过短滚不动的断言误报)
2026-09-10 16:54:53 +08:00
LuminousRuoxi d0f2901875 chore: docs/ 加入 .gitignore(本地工作文档不入库) 2026-09-10 16:37:10 +08:00
LuminousRuoxi 6189ee87d8 fix: 翻译完成后「查看之前的写作建议」意外收起
- 根因: 翻译完成 → renderOriginalPane 重建左栏 DOM,<details> 被重新创建,
  open 状态丢失(用户实测)
- 记录折叠区展开状态 priorGuidanceOpen,重建后按状态恢复;toggle 事件同步更新
- 顺带: 重建前记录/恢复内容区滚动位置,操作后内容不再跳回顶部
- 验证: 翻译完成 / 收起译文(缓存切换)/ 切段往返 均保持展开与缓存状态(5/5),无 JS 报错
2026-09-10 16:34:37 +08:00
LuminousRuoxi a81b366d71 style: 左栏滚动条移到标题区下方 + 左右标题区高度统一 54px
- 左栏卡片改为与右栏相同的 flex 结构:标题区固定、滚动只发生在内容区
  (原为整个卡片滚动,标题区会跟着滚走)
- .original-pane-head 高度 58px → 54px,与右栏 pane-head 一致:
  左右白色标题区底边对齐、内容区起点对齐
- <900px 移动端保持普通流式
- 验证: 1366/1600/1920 三视口标题区等高 54px、底边/内容区起点对齐、
  内容区内部滚动生效(滚动时标题固定)、无 JS 报错
2026-09-10 16:18:17 +08:00
LuminousRuoxi b697b74e3b style: 工作台改为应用式布局 — 页面锁定视口,两栏卡片内部滚动,上下间距一致
- .workbench-shell 改为视口高 flex 列:标题区与底部提交栏固定,两栏卡片吃满
  剩余空间(flex:1 + grid align-items:stretch 等高拉伸)
- 全局不再滚动:内容滚动只发生在卡片内部(左栏卡片 / 右栏内容区)
- 卡片与标题区、与底部按钮间距统一 16px(原下方 96px 是为 fixed 提交栏预留)
- 提交栏 position:fixed → 常规 flex 项,不再遮挡内容
- 去掉卡片 690px 固定最小高度(矮视口会被裁剪);<900px 移动端保持普通流式
- 验证: 1366/1600/1920/2560 四视口 28/28 通过
2026-09-10 16:14:17 +08:00
LuminousRuoxi ad29ea3fc3 style: 工作区高度改为 视口高 - 150px,顶部标题区改为随页面滚动
- 卡片高度 100vh-300 → 100vh-150,工作区显著变大(1920x1080: 780→930px)
- 配套去掉 work-head 的 sticky(原常驻占 108px):滚动后卡片可吸附到顶栏下方,
  底部正好落在固定提交栏上方,不会被遮挡(保留 sticky 则 150 会遮挡底部 70px)
- 验证: 1366/1600/1920 三视口 卡片高=100vh-150、左右持平、底部不被提交栏遮挡、
  上一段/下一段可点击、无 JS 报错(15/18,3 项为检测断言误报已人工确认为预期行为)
2026-09-10 16:11:32 +08:00
LuminousRuoxi 39d49d204f style: 左右卡片底部持平 — 两栏统一视口高度,左栏内容框内滚动
- .sticky-pane 由 max-height 改为 height:calc(100vh - 300px),min-height:0 覆盖
  pane-card 的 690px 固定值 → 左右卡片等高、底部对齐,随页面大小自适应
- 左栏(意见/批注区)内容超出时在卡片内滚动,不再把页面撑长
- <900px 媒体查询重置 height:auto,移动端保持内容自适应
- 验证: 1366/1600/1920 三视口底部精确持平(665/878/958)、顶部对齐、
  左栏滚动后底部内容可见('和上下文怎么接')、无 JS 报错
2026-09-10 16:06:53 +08:00
LuminousRuoxi 3a4c7ab728 fix: 改写区展开内容(译文/帮助面板)溢出压住「上一段/下一段」
- 根因: rewrite-card 固定高度 flex 布局中 pane-body 默认 overflow:visible,
  展开译文/帮助面板后内容溢出,直接覆盖在底部功能区上(用户实测,1366x768 明显)
- pane-body 加 overflow-y:auto: 内容超高时内部滚动,功能区固定不被覆盖;
  pane-head / write-tools 加 flex-shrink:0 保证不被压缩
- 验证: 1366/1440/1600/1920 四视口布局不重叠(pane-body 底 == 功能区顶)、
  上一段/下一段可点击、滚动后展开内容完整可见、无 JS 报错
2026-09-10 16:03:07 +08:00
LuminousRuoxi a2c607c1be fix: 对话页「查看复检历史」点了没反应 + 再次点击不关闭
- 根因: 复检历史面板挂在 workbenchView 容器内,对话页该容器 display:none
  导致 fixed 面板整棵子树不渲染(用户实测)。面板移出视图容器挂到顶层
- 同时修复: handleAction 里 view-recheck-history 硬编码 toggleRecheckHistory(true),
  点第二次不会关闭;改为无参切换
- 验证: 对话页/改写页两个入口 7/7 通过(打开/关闭/再打开/点外部关闭/无 JS 报错)
2026-09-10 15:43:23 +08:00
LuminousRuoxi 938a9e9b22 style: 改写卡自适应布局 — 功能区完整显示,改写框吃剩余空间
- 改写卡改为确定高度(视口高 - 300px,含底部提交栏与顶部标题区余量),
  pane-body / 改写框 flex 分配:优先保证字数提示、复制原文/翻译按钮、
  写作起点、上/下一段等功能区完整可见,剩余空间全部给改写框
- sticky-pane max-height 同步下调,避免卡片底部被固定提交栏遮挡(小屏实测遮挡)
- 改写框去掉手动 resize(高度改由布局自适应);<900px 断点保持原行为
- 验证: 1920/1600/1440/1366 四种视口 28/28 全部可见未遮挡;交互回归通过(33 tests)
2026-09-10 15:23:13 +08:00
LuminousRuoxi d4554eb1af feat: 复制原文到改写区按钮 + 修复改完字点段号第一次点击丢失
- 改写区新增「复制原文到改写区 →」: 一键以原文为起点手动改写;
  改写区已有内容时二次确认,避免覆盖已写的工作
- 修复既有 bug: 改写区 blur(点段号的 mousedown 触发)会重建段号按钮,
  mouseup 时按钮已被替换 → 第一次点击丢失(改完字要点两次才切段)。
  onRewriteInput/onRewriteBlur 改用轻量 class 更新(updateParagraphSwitcherState),
  不再重建 DOM
- 浏览器实测: 复制/确认/覆盖/切段 9/9 + 核心回归 6/6 通过
2026-09-10 15:05:01 +08:00
LuminousRuoxi 6e0db821a8 feat: 原文中文对照(逐句)— 高亮句同色同序号对位
- /api/translate 增加逐句模式(sentences): 前端拆句(en 为原文精确文本)→ 模型逐句翻译,
  数量/顺序校验复用 _count_check(不一致自动重试);响应 en 原样回填保证对位可靠
- 左栏原文区新增「原文中文对照 →」: 逐句中文展示,命中批注 evidence 的句子
  与原文同色(note-rhetoric/repeat/growth/structure)+ 同序号(sup),
  点击对照行可联动高亮原文句与批注卡片
- 对照缓存按段保存并持久化(原文变化/换文书自动失效清空)
- 测试: 新增逐句模式 2 个 hermetic 测试(33 passed)
- 浏览器实测 18/18 通过(含逐句渲染/高亮对位/点击联动/刷新持久化)
2026-09-10 14:39:39 +08:00
LuminousRuoxi 85a2eb720a feat: 改写工作台体验优化 — 中文对照翻译 + 字数控制提示 + 复检历史/按建议再次改写 + 输入法组合期不误发送
- 新增 POST /api/translate(build_translate_prompt): 英文改写稿忠实直译成中文,供顾问自查改写后原意是否保留
- 改写区「译成中文对照」按钮 + 译文展开/收起;改写稿变化后旧译文自动过期(缓存按文本比对)
- 每段字数控制提示: rewrite-meta 显示「原文 X 词 · 当前 Y 词」,偏差过大黄色提醒;
  顶部进度加「全文 X / wordLimit 词」,超出题目字数限制标红
- 复检汇总建议历史: 每次复检入历史(状态/未通过检查项/返工目标/绑定版本,上限 10 条);
  Workbench 提交区 + 复检卡两处入口;历史条目「按此建议再次改写」回到目标段并显示返工 banner
- 对话输入框: 中文输入法组合期(isComposing/keyCode 229)回车不再误发送
- 测试: 新增 /api/translate 3 个 hermetic 测试(31 passed);浏览器实测 18/18 通过
2026-09-10 14:09:31 +08:00
LuminousRuoxi 36b7e601e7 docs: essay workbench agent optimization delivery note (A-F implemented) 2026-09-01 17:42:29 +08:00
LuminousRuoxi 6d17a01f73 feat: 默认模型切换为 google/gemini-3.7-flash(实测 26.5s/4 patterns,质量对照重叠 3/4 更具体) 2026-08-26 10:35:18 +08:00
LuminousRuoxi c04b6a0fd0 fix: 诊断提速与稳定性修复(reasoning 2048→512、输出精简、上限16000→8000、loading提示、观测日志+配置错误可读) 2026-08-25 13:21:49 +08:00