Commit Graph

11 Commits

Author SHA1 Message Date
caoqianming 5caa3db62e perf(web): 消息尾部窗口分页 + 向上滚动加载更早 + 切 task loading 占位 + bump 0.12.14
切 task 卡顿:/v1/tasks/{id}/messages 无分页全量拉 + 前端全量渲 DOM,消息多时两段成本线性涨。

- 后端 list_messages 加可选 limit/before_idx:不传=旧行为(升序全量,仅多返 has_more,向后兼容);传 limit 取尾部最近 N 条,before_idx 取更早一批,响应恒含 has_more
- 前端 selectTask 进来立即换「加载中…」占位(治感知);loadMessages 默认 limit=60
- 新增 loadEarlierMessages + _msgScrollObserver(复用 task list sentinel 范式):顶部 sentinel 进视口自动 prepend 更早一批后整窗重渲,锚回滚动位不跳视口
- state 加 loadedMessages/msgHasMore/msgLoadingEarlier;dev.html 加 .msg-top-sentinel 样式

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-15 11:30:42 +08:00
caoqianming 977923b6cf feat(web): 左栏任务筛选区默认折叠(偏好仍持久化)+ bump 0.12.8
进页面只见「筛选 ▸」一行,点开才展开;用户显式展开过(localStorage 存 "0")才默认展开,否则一律折叠。已选筛选条件折叠后仍生效。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-15 08:56:46 +08:00
caoqianming d30435198c feat(web): 模型选择瘦身 — 对话模型常驻 + 生图/生视频收进 ⚙ 弹层 + bump 0.12.4
- meta 行原三个带标签下拉(模型/生图/生视频)占满整行 → 高频对话模型常驻可见可切,
  低频生图/生视频收进一个「⚙ 媒体」fixed 弹层(点开才渲染 select)
- 行为不变:媒体模型选中值仍只进 state.*,随下条消息 image_model/video_model 发;
  send 读 state 不读 DOM,迁移安全;两个 select 都没配时连 ⚙ 都不画

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-13 13:07:51 +08:00
caoqianming 18f702886f feat(web): 左栏筛选区可折叠(默认展开,偏好持久化)+ bump 0.12.3
- 搜索/状态/目录/排序四控件归到两行 .task-filter-row,标题行加「筛选 ▾」toggle
- 默认展开,折叠只藏 UI(已选条件仍生效),偏好存 localStorage(同 pane 折叠范式)
- 折叠后左栏顶部 4 行→2 行,任务列表可视区更高
- 状态下拉并入筛选区(flex),搜索框 flex:2 更宽;目录/排序合一行用 title 提示

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-13 12:58:33 +08:00
caoqianming ae9790601a refactor(web): 中栏操作收进 ⋯ 菜单 + 消息阅读限宽 + 色彩收敛 + bump 0.12.2
- 中栏顶栏 5 个平铺按钮(导出/清空/完成/废弃/删除)→「完成」+「⋯」菜单,
  菜单复用 taskMenuItems(过滤 complete),与任务行同一范式;破坏性操作不再平铺易误点。
  顺带让菜单「清空」按 run_status 也禁用(修运行中 409-after-confirm 小坑)
- 消息限宽:.msg max-width 92% → min(92%,48rem),user 气泡 min(92%,36rem),宽屏可读性↑
- 色彩收敛:颜色=后果(完成/下载绿、废弃橙、删除红),导出/清空中性不着色;移除紫/蓝冗余

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-13 12:52:56 +08:00
caoqianming 1f57bbd201 fix(web): 导出按钮简写 + 任务菜单加清空 + 修移动端 task 滚动 + admin 自适应 + bump 0.12.1
- 顶栏「导出对话记录」→「导出对话」,与「清空对话」对齐(dev.html + chat.js 菜单 export 项)
- 任务菜单(每行 ⋯)新增「清空对话」,复用 clearMessages;dropdown 加 .act-clear 紫色
- 修移动端 task 列表无法滚动:手机断点 #pane-left 误用 display:block 致 #task-scroll
  flex:1 失效被 overflow:hidden 截断;改 display:flex 恢复滚动
- admin 移动端自适应:header 紧凑化 + .card-head/.ctrl 允许换行,避免窄屏横向溢出

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-13 12:41:53 +08:00
caoqianming 4f6e879050 feat(web): systemctl restart 优雅 drain in-flight run,不再误标 error
此前 restart 硬杀 BG run 线程,下次启动 reaper 把所有 running/cancelling
标 error: server restarted before run finished —— 用户一多就不能随便重启。

单实例止血,零 DB 改动:
- lifespan 加 draining(Event) + inflight 登记表(顺手修 create_task 不留引用
  可能被 GC 的旧坑);finally 先拒新 run → await 收尾 → 超 drain_timeout 转
  协作式 cancel(= 用户按停止,标 idle 不报 error、可重发)→ 超 cancel_grace
  仍没退的留给 SIGKILL(最坏退化 = 改前)
- POST /messages:draining 期返 503 + Retry-After;起 run 登记 inflight
- main.py uvicorn 加 timeout_graceful_shutdown=5(否则长连 SSE 挡在 drain 前)
- config/agent.yaml 加 shutdown 段(drain 30s / grace 15s,偏短更安全)
- dev SPA chat.js 发送包退避重试(503 背压 + 交接拒连都重试 ~26s)

部署强耦合:unit TimeoutStopSec 10→90(必须 > drain+grace+sandbox 清扫余量),
已写进 RUN.md unit + 故障兜底。B 蓝绿(零 503 窗口)留作触发信号后再做。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-10 10:54:43 +08:00
caoqianming 824f746571 fix(progress): 停压 task_progress 参数修进度还原 + 进度区移到对话区顶部
问题1(进度不对): 上下文压缩把旧 task_progress tool_call 参数换成
{"_compacted":true,"step_id":"sX"} 这种像合法调用的标记, 既毒化模型让它
照抄出残废 update_step(丢 step.status)入库, 又让前端 applyProgressAction
读不到 args.step → 步骤永停 pending。修复: task_progress 参数一律不压缩。

问题2(没像 codex 在顶部): 删掉每条消息卡内联进度块, 进度统一只在对话区
顶部单一 dock 实时显示(钉顶不滚); 全部完成时折叠成一行摘要。prompt/tool
描述改为跑完标 completed 而非 clear, 留住全绿收尾。

校验: unittest test_context_compaction/test_task_progress_tool 12 过;
node --test frontend_task_progress 2 过。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-08 09:52:44 +08:00
caoqianming 4ee09976ee Show task progress above composer 2026-06-08 09:04:43 +08:00
caoqianming 8616ba2b56 Add task progress tool 2026-06-08 08:44:16 +08:00
caoqianming 15ecf45c93 refactor(dev): 前端模块化 Step 2 收官 — 抽出 chat.js,main 缩成 75 行入口
最后也最缠的一块:任务列表(浏览/筛选/滚动)+ selectTask 切换 +
renderChatMeta/模型下拉 + renderMessages + live-run 助手 + sendMessage/cancel +
fetchSse/handleSseEvent + 润色/粘贴文件 + 完成/废弃/删除/导出/清空
(原 main 连续区 64–1132)→ chat.js(1086 行)。

决策:合一个 chat.js 而非强拆 tasks.js+stream.js —— 二者共享
state.liveRuns + chat-stream DOM + run 生命周期,live-run 助手被
selectTask 与 SSE 机器两边调用、骑墙;强拆会制造双向各 ~4-5 个 import
且边界不自然。

- 导出 loadTaskList / loadModels / selectTask;embed/files/newtask 对这
  三个的 import 从 ./main.js 改指 ./chat.js;formatUploadProgress 加 export。
- chat 不调 enterApp → 与 main 无环。
- main.js 仅留 enterApp(编排)+ loadStorage + Esc 关栈 + boot = 75 行入口,
  import 精简到 11 行(layout/markdown/media 不再被 main 直接引用,但经
  chat 仍在依赖图、副作用照常)。

校验升级:node 全检 + import/export 一致性 + 从 main BFS 的模块可达性
(14/14 可达,确保副作用模块不掉出图)。

dev.html 4087 行单文件 → 14 个零构建 ES module + 纯 HTML;main 2719→75。
路径 1(拆文件)完成。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-08 08:09:53 +08:00