caoqianming
|
12a2289de2
|
style(web): 卡片布局改左大右小,⚙ 固定宽度
卡片左侧占主空间(点开对话),右侧「⚙」固定宽度 28px(点开弹框),
点击更易触发。未绑定/已绑定无对话卡片也加右侧 ⚙ 管理。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
2026-06-26 12:17:32 +08:00 |
caoqianming
|
013cbc28b5
|
fix(web): 卡片 ⚙ 按钮打开弹框管理
已绑定且有对话的卡片:⚙ 按钮打开弹框管理,拦截点击不触发 selectTask。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
2026-06-26 11:28:14 +08:00 |
caoqianming
|
a6d00b24ff
|
feat(web): 渠道卡片收拢绑定管理 + 删 rail 按钮 + bump 0.28.1
把渠道绑定/对话/管理全部收进「新建任务」下方的卡片,删掉左下角
rail「微信」按钮(精简页面)。后端 /v1/channel_tasks 返回
{ wechat: { bound, task }, wecom: { bound, task } },前端渲染三种卡片:
未绑定(点绑定)/已绑定无对话(占位)/已绑定有对话(点进+⚙管理)。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
2026-06-26 11:19:45 +08:00 |
caoqianming
|
133e350428
|
style(web): 渠道卡片改并排省纵向空间 + bump 0.27.4
接 0.27.3:两张渠道镜像对话卡片(微信/企业微信)从竖排改并排
(#channel-cards flex row,各 flex:1);窄栏内图标左、名称 + 条数·时间
堆两行(新增 .cc-body 列容器)。绑定弹框(左下角「微信」rail 按钮)保留
不动 —— 它是绑定/解绑/测试推送唯一入口,与卡片职责互补不重复。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
2026-06-25 12:39:25 +08:00 |
caoqianming
|
7dfdf4c73b
|
feat(web): 微信/企业微信对话改成左栏固定卡片 + 企业微信也只读 + bump 0.27.3
把渠道镜像对话(每用户每渠道唯一的常驻只读对话)从「任务列表置顶行 +
绿徽章 + 绿边」改成「新建任务下方两张固定卡片」,与可滚动任务列表分离、
常驻可见;顺带补企业微信对话的 web 端只读锁。
- 后端 /v1/tasks 用 coalesce(channel,'web').notin_(CHANNEL_MIRROR_KINDS)
排除渠道任务并删掉 case() 强制置顶;新增 GET /v1/channel_tasks 返回
{wechat, wecom} 摘要(复用 _task_dict,无则 null)
- 前端加 #channel-cards 卡片块(:empty 自动隐藏)+ loadChannelCards/
syncChannelCardActive;移除列表行已失效的绿徽章逻辑
- applyChannelComposerLock / sendMessage 守卫从硬编码 channel==='wechat'
改读 CHANNEL_BADGE,微信 + 企业微信都 readonly,提示文案按渠道动态
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
2026-06-25 12:32:12 +08:00 |
caoqianming
|
b5cfce72b5
|
feat(wechat): web 端微信 task 只读镜像,锚定微信为单一交互入口 + bump 0.25.1
web 端打开 channel=wechat 的常驻 task 原能正常发消息,但 web→微信单向
不同步(web 发的走通用端点 → _run_agent_bg,不经过 inbound loop 里
send_text 回微信那段,微信侧零感知);微信→web 则同步(同一条 task)。
不做双向打通:回微信需 context_token、只能从入站拿且 24h 过期,双向同步
会被该窗口拖成"有时同步"(不可预测)+ 两入口并发写歧义。改为 web 端只读
镜像,交互权威单一锚定微信;主动推走 wechat_push / 定时简报。
- chat.js: applyChannelComposerLock(selectTask 后调)对 wechat task 置
chat-input readOnly + 改 placeholder 引导去微信 + 禁润色;sendMessage
入口加 channel 守卫(Enter 兜底)
- dev.html: .readonly-locked 置灰样式
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
2026-06-24 16:30:22 +08:00 |
caoqianming
|
340786a42f
|
feat(web): 微信任务徽章改品牌绿 + 微信 logo + 整行绿边 + bump 0.23.1
上版徽章复用 .badge.active(蓝灰)与旁边「进行中」状态徽章撞色、不显眼。
新增 .badge.wx(微信绿 #07C160 + 白字 + 内嵌微信 logo SVG)与 .task-row.wx
(绿色左边框 + 极淡绿底 + hover 加深),让置顶的微信任务从普通任务里跳出来。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
2026-06-24 11:23:34 +08:00 |
caoqianming
|
85336ccb7e
|
feat(wechat): 微信对话 task 渠道标记 + 列表置顶(channel 字段)+ bump 0.23.0
tasks 加 channel 列(web/wechat,migration 0013,server_default='web' 回填存量,
并把 description='(微信 ClawBot 对话)' 的存量 task backfill 成 wechat)。微信常驻
task 后端强制置顶(列表查询前置 case pin 表达式,跨分页稳定),前端任务名前打绿色
「微信」徽章一眼可辨。channel 仅 INSERT 写定,后续 upsert/save 不传不覆盖。
- core/storage/models.py: Task.channel 列
- db/migrations/.../0013_task_channel.py: 加列 + backfill
- core/storage/utils.py: ensure_local_task_row 加 channel 参数
- web/app.py: 微信建 task 传 channel=wechat;_task_dict 透出;列表 pin 置顶
- web/static/js/chat.js: channel===wechat 打徽章
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
2026-06-24 11:12:16 +08:00 |
caoqianming
|
c569438d5f
|
fix(web): 顶栏 token 计量栏回复后不刷新 + bump 0.22.1
提问→助手答完后,对话顶栏「总 token·缓存命中·花费」停在发问前旧值,
要切走再切回才更新。根因:计量栏读 state.taskMeta,而它只在 selectTask
里重拉;SSE 收尾的 fetchSse finally 只刷列表+消息,从未重拉 meta。
修:finally 里当收尾的是当前可见 task 时补一次 GET /v1/tasks/{id} →
重置 state.taskMeta → renderChatMeta(),失败 try/catch 吞掉不打断收尾。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
2026-06-24 09:08:19 +08:00 |
caoqianming
|
d412aa6b24
|
fix(web): 消息目录点第一个圆点误高亮第二个 + bump 0.20.4
跳转锚点(block:center)与活跃判定锚点(顶线 80px)不一致:第一轮
上方无内容无法居中、被钉到顶端,短轮时下一轮卡片顶也落进 80px 带内
→ 越界高亮第二个圆点。改跳转为 block:start(同锚点)+ .msg
scroll-margin-top:16px,活跃容差 80→24 对齐。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
2026-06-23 08:56:02 +08:00 |
caoqianming
|
be813629b2
|
feat(media): seedream i2i 改图 + 前端 paste 路径注入 + bump 0.15.0
- seedream 加 reference_images(v1 单图):传已有图路径做像素级改图,
不传=文生图行为 100% 不变(向后兼容)。路径解析抽到 tools/image_ref.py
(三形态路径 + 强制落 user_root 内防越界 + 扩展名/大小校验)
- 前端 chat.js:sendMessage 把粘贴图路径作 [用户上传的参考图] 行注入正文,
修了粘贴图路径到不了模型的既有缺口("上传外部图→改图"才能定位文件)
- 引导:imagegen SKILL 删旧"不接图像输入"+ 加改图(i2i)专段,纠正
"该 i2i 却重新文生图丢原构图";agent_builder 媒体 block + SKILL_LIST 同步
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
2026-06-16 16:18:18 +08:00 |
caoqianming
|
1cfeb000a6
|
feat(web): ask_user 工具 — 回复里渲染可点击「方案确认」选项卡 + bump 0.14.0
agent 在真正的分叉点(2-4 个互斥方向且选择会实质改变后续动作)调用 ask_user,
前端渲染可点击选项卡:点一个即作为回复继续,或不点直接用文字讨论。
收窄定位防 agent 变爱问(高轮数烧 token 已知痛点),系统提示严格约束使用条件。
与轮次模型同构、无阻塞:ask_user 是虚拟工具(同 task_progress 范式),loop 检测到
本步调用它就提前结束本轮、不回灌 LLM;点选项=发该选项 label 作新用户消息,零额外
LLM 往返。选项落在 tool_calls.arguments 里,刷新页面按钮还在;已答的卡自动置灰。
- tools/ask_user.py 新增 AskUserTool;core/agent_builder.py 注册
- core/loop.py 加 ask_user 提前终止分支
- prompts/system/general_v1.md 加「方案确认约定」段
- web/static/js/chat.js buildAskUserCard + SSE/历史重渲特判 + sendMessage(overrideText) + 点击委托
- web/static/dev.html 加 .ask-user/.ask-option 样式
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
2026-06-16 11:23:59 +08:00 |
caoqianming
|
91e200ef4f
|
feat(web): 消息目录-右侧悬浮圆点轨道导航(ChatGPT 式)+ 双向分页 + bump 0.13.0
右缘悬浮圆点轨道:每点=一轮"我"的提问,hover 展开标题,点击滚动定位+高亮,
滚动自动高亮当前轮;覆盖全部轮次(非仅当前窗口)。
后端:新增 GET /v1/tasks/{id}/outline(只取 role=user 的 idx+首行片段,不回传整
payload);list_messages 加 after_idx 参数 + has_more_after 响应,支持向下翻页
(从目录跳旧消息后补回下方未加载的新消息)。纯增量,旧前端不受影响。
前端:消息卡补 data-idx 锚点;jumpToMessage 已加载则 scrollIntoView、未加载用
before_idx 拉居中窗口再定位;refreshOutline 并入 selectTask 并发拉 + run 收尾刷新;
dev.html 加 #msg-outline-rail(容器 pointer-events:none 不挡滚动条、仅圆点可点),
手机端隐藏,embed 页 null-safe。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
2026-06-16 08:52:39 +08:00 |
caoqianming
|
82feecef06
|
perf(web): 切 task 并发拉 meta+messages + 默认窗口 60→30 + bump 0.12.16
selectTask 里 meta 与 messages 原本串行 await,改 Promise.all 并发省一个 RTT;
MSG_PAGE 60→30 降首屏传输与 markdown/highlight 同步渲染量。切 task 慢非索引问题
((task_id, idx) 唯一索引已覆盖主查询),故只优化前端串行与窗口大小。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
2026-06-16 08:21:26 +08:00 |
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 |