Commit History
Yesterday
-
shan chu tupian yuchong xiazai, chidu gengxin an zhen he bing
xiaolongmr36b3bb0 -
houtai xintiao jiang pin dao 50s, fangkuan zaixian chuangkou dao 120s
xiaolongmrpresence xintiao shi wei yi "qie dao houtai ye zhao da" de quanju lunxun, xian shang shi ce dan zhe yi xiang jiu you 300+ req/s, er rongqi zhi you 2 ge gongxiang vCPU。 - qian tai: 25s (bu bian, hu ying bu shou ying xiang) - hou tai: 50s (jiang yi ban) - fuwu duan zaixian chuang kou: 60s -> 120s 50s x 2 = 100s < 120s, lian diu liang ci xintiao reng suan zaixian, bi yuan lai de 25s/60s geng bu rongyi wu pan li xian。 qie hui qian tai shi li ke bu yi ci, zaixian renshu dangchang bian zhun。 zhen ji: artifacts/_visibility_gate_test.py 10/10; tsc / eslint jun lv。9340872 -
降低线上轮询压力:后台标签页暂停轮询、关闭 access log
xiaolongmr线上容器(cpu-basic,2 共享 vCPU)实测 1841 req/s,超出承载数倍, 导致连返回静态 JS 都要 55 秒。日志拆解后,热点全是自家前端的全局轮询接口: /auth/session 375/s /api/chat-room/unread 359/s /api/chat-room/direct-conversations 350/s /api/presence/ping 334/s /api/announcements 106/s 四项改动(均不改变任何功能,用户感知不到差别): 1) Dockerfile 去掉 --access-log 实测 access log 占日志体积一半(约 285 KB/s、1800 行/秒),容器只有 2 核,每条请求都多一次格式化 + write 系统调用。注意 main.py 末尾的 uvicorn.run(access_log=False) 在线上不会执行(CLI 启动),所以必须改这里。 2) use-chat-room-unread:只在页面可见时轮询 这个 hook 挂在全局导航,每个标签页都在跑,含切到后台/被遗忘的标签页。 后台没人看角标,请求却照打。切回页面时立刻补拉一次。 3) announcements-popover:同样只在可见时轮询 该组件在顶栏挂了 2 份(移动端/桌面端各一),每个标签页跑两份。 4) use-auth-guard:权限兜底同步 5s → 30s 原本是 force 校验(绕过本地缓存直打服务端),是全站最重接口、占请求 20%。 权限和登录态不会 5 秒一变;focus / visibilitychange 仍会立刻强制校验一次, 真实感知比 30 秒更灵敏。 presence 心跳保持后台上报(约 25s)不变 —— 那是「在线人数」要统计后台标签页的 有意设计,属功能行为,未改动。 真机验证(artifacts/_visibility_gate_test.py)10/10 通过: 可见时 unread / direct-conversations…d188720
2 days ago
-
聊天室未读角标:改成红色圆形气泡,并把私聊未读一并计入
xiaolongmr1) 样式:顶部「聊天室」导航项的未读提示原来是纯文字红色数字, 改成微信/QQ 那种红色圆形气泡(rose-500 底 + 白字 + rounded-full)。 用 min-w-4 + px-1 让个位数是正圆、两位数自然撑成胶囊, 避免固定 size-4 时 "99+" 溢出;补 aria-label 标注未读条数。 2) 计数:原来只算公共大厅未读,私聊未读拿不到。 useChatRoomUnread 改为 大厅未读 + 所有私聊未读之和, 两个请求并发发(Promise.all),传私聊已读位置整表给服务端做差集。 真实机验证 9/9 通过(含「造 2 条私聊 → 角标 +2,读掉后回落 2」), 回归 _chatroom_unread_test / _pin_test / _api_e2e 共 49 项全过。d24ebec -
聊天室:消息里的 URL 自动变成可点击链接(新标签页打开)
xiaolongmr- 改造 `renderContent`:原来只处理 @昵称 高亮,现在 @高亮 与 URL 链接化并存。 非 @ 片段再走一遍链接识别,两套 pattern 不互相干扰。 - ⚠️⚠️ **URL 正则必须把中文标点排除在字符类外**: 中文没有空格,`https://example.org。以及后面的话` 若不在 `。` 处停下, 会把整个句子吞进链接里 —— 真机实测踩到,第一版就是错的。 同时 ASCII 尾部标点(`)]}>.,;:!?`)在用 trimUrlTail 剥掉。 - ⚠️ 故意**不**匹配裸域名(`abc.com`):中文聊天里「图片.png」「3.5 折」极易误判。 - ⚠️ `target="_blank"` 必须配 `rel="noopener noreferrer"`,否则新页面能通过 `window.opener` 反向操作当前页。 - ⚠️ 链接 `onClick` 要 `stopPropagation()`:消息区外层有点击处理。 验证:解析逻辑 11 例单测 + 真机(Playwright)8 项断言全过, 含「中文句末标点未被包进链接」「裸域名不链接化」「点击真的开新标签页并导航到目标地址」。4ec754b -
聊天室:新增「回到底部」按钮,与画图页同款
xiaolongmr- 离开底部(>80px)才出现,点一下平滑滚回最新;回到底部自动收起。 - ⚠️ 聊天室滚动在**内层消息容器**(listRef),不是 window —— 不能照抄画图页的 `window.scrollTo`,必须滚 `el.scrollTo`。 - ⚠️ 直接改 `el.scrollTop` 不一定触发 onScroll,所以自动滚到底后要**手动同步** 按钮状态,否则会出现「已经到底了按钮还挂着」。 - 按钮用 `absolute bottom-full` 贴在输入框上方(footer 是 relative,父级不裁剪); ⚠️ 外层容器必须 `pointer-events-none`、只给按钮本身 `pointer-events-auto`, 否则这块透明区域会挡住下面消息区的点击。 - 消息区加 `data-chat-room-list` 钩子:同页有 3 个 `hide-scrollbar` 容器, 按 class 选会选错(真机验证脚本实测踩到)。 验证:真机(Playwright + Chrome)5 项断言全过 —— 按钮渲染 44×44、底部时隐藏、 上滚后出现、点击后距底 0px、回底后再次隐藏。d9165c3 -
聊天室:修复置顶 422,未读角标改挂到用户行
xiaolongmr置顶报 422 的根因: - 前端把 body 做了 JSON.stringify 再交给 httpRequest,而 httpRequest 是直接把它 当 axios 的 data 传下去的 —— **传字符串时 axios 不会自动补 Content-Type: application/json**,FastAPI 就把 body 当非 JSON, 报「Field required」→ 422。 - 修法:改成传**原始对象** `body: { pinned }`,与文件里其他 POST 调用一致。 (curl 复现:不带 Content-Type 的字符串 body → 422,带上 → 200。) 未读角标的位置与语义: - ⚠️ 不再把「会话数」红色角标挂在「私聊」分组标题上 —— 那个数字分不清是谁发来的。 改成挂在**每个用户那一行**(对方昵称右侧),显示「这个人有几条我没看」。 - ⚠️ 原来 direct_conversations() 的 total 是「所有非我发的消息总数」, 没有已读概念 → 角标只增不减(读完也不消)。现在按已读位置过滤。 - 已读位置**不落库**:存 localStorage(`chatgpt2api_chat_room_direct_read`, peer_id → 已读到的最大 id),接口用 `mark=peer:last_id,...` 把整张表带过去, 服务端只数 `id > last_read` 的对方消息。这样不必新建「每用户每会话已读表」。 - ⚠️ 私聊的已读位置**与公共大厅分开存**:两边消息 id 不同源,共用一个 key 会互相顶掉。 - 打开会话 / 正在看该会话时收到新消息 → 立刻写已读位置并广播事件, 收件箱监听该事件即时重拉,角标当场归零,不必等下一个轮询周期。 - `_parse_marks` 把前端输入一律当不可信:格式不对整段丢弃,宁多显示未读也不能 500。 另外顺手改:收件箱摘要里自己发的消息加「我:」前缀(否则看起来像对方说的), 已撤回的显示「[消息已撤回]」而不是空白。 验证:四套聊天室测试共 64 项全过(服务层 24 + HTTP 11 + 用户侧端到端 15 + 未读 14)。 tsc / eslint 全绿。已清…ca6cef4 -
聊天室:管理员置顶公告 + 修复私聊收不到/回不了
xiaolongmr置顶(仅管理员,服务端强制): - 消息表新增 pinned_ts / pinned_by 两列,_row_to_message 下发 pinned / pinned_at。 - set_pinned 只放行 admin;已删除的消息不能置顶;撤回时一并清掉置顶。 - 新增 GET /api/chat-room/pinned 与 POST /api/chat-room/messages/{id}/pin。 - 置顶条**独立于翻页列表**:置顶消息可能早就不在当前页,仍要常驻顶部。 - 前端在 header 与消息区之间加置顶横幅,多条默认只露第一条(可展开), 点击跳转到原消息(不在当前页时给提示,不静默无反应)。 修复「管理员私聊用户,用户看不到消息,也无法回复」——两个独立成因: 1) 权限判定用错:_assert_can_direct(只允许 admin)被误用到读历史/回复路径, 导致收件人侧一律 403。拆出 _assert_can_access_conversation(会话双方可访问), 读历史与「回复已有会话」走它;只有「发起全新会话」才要求 admin。 ⚠️ 判定新会话不能只看「me 在参与者里」——新会话的键就是 dm:me|peer,恒成立, 必须用 _has_history() 查是否有实际往来,否则普通用户能私聊任何人。 2) 收件人没有入口:原未读统计只看公共大厅,收件人根本不知道有人私聊自己。 新增 direct_conversations() + GET /api/chat-room/direct-conversations, 前端侧栏加「私聊」区块(头像/昵称/摘要/在线点 + 计数徽章)。 验证:服务层 24 项、HTTP 接口 11 项、用户侧真实鉴权端到端 15 项,共 50 项全过。 后端全量测试 948 passed,失败 26 项均为既有环境漂移(chrome 指纹版本、导航迁移), 与本次改动无交集(chat_room 相关 0 项失败)。80c80f8 -
聊天室:图片改用灯箱查看,修复 @ 用户面板被裁掉
xiaolongmr1. 聊天图片不再新标签页打开 原本用 <a target="_blank"> 包图片,点击会跳新标签页。改为复用站内已有的 ImageLightbox(Fancybox),点击原地放大;并把当前已加载消息里的图片一并 传入,灯箱内可左右翻看,不用退出去再点下一张。 2. 修复 @ 唤出面板被遮挡 @ 面板是 `absolute bottom-full`(贴在输入框上方),而 PromptComposerSurface 默认带 `overflow-hidden`,会把面板整块裁掉 —— 所以看起来像「没弹出来」。 按 chat-composer 的既有做法,在面板打开时给 Surface 加 `z-50 overflow-visible`。0fdc4c2 -
移除画图页的客服聊天挂件
xiaolongmr删除 web/src/app/image/page.tsx 里注入 //dh.z-l.top/chat.js 的 useEffect, 普通用户画图页不再加载该挂件。 背景:zh 挂件由 ecf6886b 加入主线;zlcy/li 远端曾用 e0d9a201 单独 revert 掉, 但后续把 zlcy/li 强制同步到主线时又把挂件带回了线上,故在主线一并移除。2c67eea -
聊天室:隐藏消息区与侧栏的滚动条
xiaolongmr给消息区、侧栏在线列表、@ 唤出面板的 overflow-y-auto 容器加上站点现成的 hide-scrollbar 工具类(globals.css 已定义,画图页消息区同款)。 滚动功能不受影响,只是滚动条不再显示、也不再占位。77baeb5 -
聊天室:头像回退微信头像、复用画图页输入框、撤回删除、布局收口
xiaolongmr头像 - 根因是聊天室与 presence 只读 identity["avatar_url"],而微信登录用户的头像 存在 wechat_avatar 里,于是恒为空、界面只显示首字占位(签到页能显示是因为 它两个字段都读)。新增 presence_service.resolve_avatar_url 统一口径: 先 avatar_url,再回退 wechat_avatar,与顶栏 / 画图页 / 批量页 / 签到页一致。 - 在线列表、消息落库、summary.me 三处都改走这个函数。 输入框 - 底部输入框改用画图页同一套 @/components/prompt-composer 部件 (Surface / Textarea / Toolbar / SubmitButton),外形与画图页完全一致。 - @ 唤出面板通过 suggestions 传入,键盘拦截走 onKeyDownCapture (返回 true 表示面板已消费该按键),粘贴图片仍走 onPaste。 撤回与删除 - 软删除:新增 deleted_ts / deleted_by 两列,不做物理删。消息 id 是前端翻页 游标,物理删会留下空洞、导致增量轮询的序列错乱。 - 已删消息的正文与图片在服务端就抹空(不能只靠前端不渲染,否则直接读接口 仍能拿到内容)。前端显示「你/某人撤回了一条消息」或「管理员删除了一条消息」。 - 权限在服务端强制:作者本人 2 分钟内可撤回(RECALL_WINDOW_SECS=120), 管理员可删任意消息。前端按钮只按同一规则决定是否渲染,不作为权限依据。 - 新增 DELETE /api/chat-room/messages/{id}。 - mergeMessages 支持就地更新:撤回后 id 不变而内容变了,若只做「去重后追加」, 轮询拉回的已删状态会被旧数据挡住,界面永远不会更新。 布局 - 输入框区去掉「所有登录用户可见,请勿发送隐私信息」。 - 左上角侧栏头部由「在线用户 + 计数 + 搜索框」改为单个「公告聊天室」标题。 - section 高度由 min-h 改为固定 h:AppShell 内层本身是 min-h-screen 加 pt-[5.25rem],section 再叠 min-h 会与之相…5b477d8 -
新增聊天室页面:登录用户群聊
xiaolongmr- 后端:services/chat_room_service.py(SQLite 只追加存储,经镜像 runtime_file 持久化)+ api/chat_room.py(消息增删查 / 汇总接口,均需登录) - 前端:/chat-room 页面,3s 轮询增量拉取、乐观发送、回车发送、500 字上限、自动滚底、日期分隔与角色徽章 - 导航:三套角色导航均插入「聊天室」(对话之后),含一次性迁移e61d03a -
Revert "失败卡片补兜底「查看官网」入口"
xiaolongmrThis reverts commit 0075c950d9b85b912a12531beb709356550fab2a.c03796c -
失败卡片补兜底「查看官网」入口
xiaolongmr请求在创建上游会话之前就被上游挡掉时(如伪装 404 "Model not found"), 卡片上没有 conversationId,原有的「查看官网对话」取证按钮不渲染。 现在这种卡片会在「重新生成这一张」左边显示一个直达 chatgpt.com 的 「查看官网」链接,方便用户自己去官网核对账号状态;后端明确 canViewOfficial=false(账号配额耗尽)时仍然不渲染。画图页与批量页同步。0075c95 -
普通用户画图页加入客服聊天挂件
xiaolongmr在 web/src/app/image/page.tsx 用 useEffect 注入 //dh.z-l.top/chat.js, 保留原样的 async 与 fold 属性(next/script 会剥掉非标准属性故手动注入), 仅 role=normal 的普通用户加载,管理员/内部账号不挂载。ecf6886 -
撤回提示词编辑器「图N 引用参考图」与 @ 唤出缩略图功能
xiaolongmr该功能几轮修复后仍无法稳定使用(@ 选图后立刻用输入法打字时空格丢失、 缩略图与光标行为异常),按用户要求整体撤掉,输入框恢复为普通 textarea。 - prompt-composer.tsx 回到 1b90ec42(功能引入前)的 textarea 版本, 移除 contentEditable chip 编辑器、序列化/光标偏移换算、@ 候选菜单、 缩略图渲染与自动补空格等全部相关代码 - 画图页 / 批量生图页 / 聊天页 / 产品图页 4 个调用方同步移除 referenceTokens 传参与 PromptComposerEditorHandle 类型标注 - 移除画图页的「写『图1』『图片1』或按 @ 都能引用参考图」提示文案 tsc 与 eslint 均通过。ce96411
3 days ago
-
提示词编辑器对齐 infinite-canvas 的 chip 输入架构,修「@选图/手打标签后空格丢失」
xiaolongmr换掉「每次输入都重建 DOM」的做法,迁移 infinite-canvas 的核心机制: - 输入时只在「DOM 序列化结果 != 目标字符串」才重建 DOM 并按字符串偏移还原光标, 普通打字(含 IME 组字)完全不碰 DOM,输入法不再被冲掉 - 空格以 DOM 为准:chip 集合相同但 DOM 缺空格时(如「的」顶掉空格的那次输入) 也会重建,杜绝「空格只在字符串里、界面看不到」的脱节 - @ 选中插入后光标落进空格文本节点内部(原先悬在节点边界,caret 矩形是 0x0) - domPointAtOffset 落 chip 边界时优先落进相邻文本节点内部,不再悬空 - 迁移 infinite-canvas 的原子删除:keydown 拦截紧贴 chip 的退格/Delete 并 preventDefault 后整块删除,避免与浏览器原生删除重复执行 真机验证(agent-browser 真实按键):@选图后立刻打字、手打标签、逐字输入、 中文混排、chip 原子边界(左右键/退格/Delete)、双 chip 相邻删除共 14 例全过。11d4116 -
提示词引用参考图:同时支持「图片1」写法
xiaolongmr用户要求除「图1」外也认「图片1」。实现为同义别名,命中任一都渲染同一张缩略图, 插入提示词时仍写主标签「图1」,不改变既有输出。 - PromptReferenceToken 新增可选 aliases;referenceIndexByLabel 与 referenceLabels 都把 label + aliases 一起收录,referenceLabels 继续按长度倒序。 倒序很关键:「图片12」必须先于「图片1」匹配,否则会被拆成「图片1」+「2」。 - 两个 image-composer(画图页 / 批量页)都传 aliases: [`图片${index + 1}`]。 - mentionCandidates 的搜索串也拼上别名,「@图片」能筛出候选。 - 缩略图角标的取号正则放宽成 /^@?图(?:片)?/,否则「图片1」会显示成「片1」。 验证: - 断言 artifacts/prompt-refs/verify-alias.mjs,23 条全绿:两种写法命中同一张图、 混用不串、越界 图片9 不命中、图片12 优先于图片1、别名在退格/左右键/补空格 四条路径上与主标签完全等价。另回归 verify-cursor.mjs 18 条仍全绿。 - 特别确认「图片1」里的「图1」子串不会被当成独立标签误匹配 (图1 要求「图」紧跟「1」,图片1 中不成立)。 - 真机 artifacts/prompt-refs/alias-check.sh,7 用例全绿:图片1/图片2 各渲染对应 缩略图、与图1 混用正确、越界图片9 不渲染、caret=4 按← 一下跳到 1、 退格整块删成「用 换」、@图片 能筛出候选、@ 回车仍插入「图1」。98186ab -
提示词引用参考图:「图N」在键盘上当成一个单位,左右键一下跨过
xiaolongmr用户反馈:参考项目里缩略图是一个字符,左右移动光标和删除都只需一下。 查 infinite-canvas 源码确认:它的 canvas-prompt-chip-input.tsx 用的是 contentEditable + contentEditable="false" 的真实 DOM chip,天然是原子节点; 而 canvas-resource-mention-textarea.tsx(textarea 版)和我们一样, 是靠 keydown 拦截模拟原子性。我们是纯 textarea,补齐这部分键盘行为。 - 新增 referenceLabelRangeAt():找出光标贴着的标签区间 [start, end)。 start 算上可选的 @ 前缀,光标停在 @ 前面时也能整块跨过去。 - 左右方向键:光标贴着标签尾部按 ← 跳到开头,贴着开头按 → 跳到尾部之后; 从标签中间按 ← 也会一下跳到开头。Shift+方向键保留选区扩展。 带 alt/ctrl/meta 修饰时不拦截(留给词级跳转)。普通文本行为不变。 - 顺带修退格的两个 bug: · 原来要求标签前面必须是行首或空格,「用图1」退格会只删掉「1」留下「用图」。 改成只要求标签结尾紧贴光标。 · 向前删的正则 ^(@?)(label) 匹配不到光标在 @ 前面时的 @,会留下孤零零的 「@」;改成 ^((?:@)?label) 一并吃掉。 - 验证: · 逻辑断言 artifacts/prompt-refs/verify-cursor.mjs,18 条全绿 (含图12 不被图1 抢匹配、@ 前缀、普通文本不误伤)。 · 真机 artifacts/prompt-refs/cursor-check.sh,7 个用例全绿: caret=3 按← → 1;caret=1 按→ → 3;caret=2 按← → 1; 退格/Delete 均整块删成「用 换」;「用图1」无空格也整块删; 普通文本按← 仍是 4→3。c98bf24 -
提示词引用参考图:@ 随手可唤出 + 手打「图N」自动补空格
xiaolongmr- @ 候选菜单改成光标前有 @ 就唤出,不再要求前面是空格或行首。 参考项目 infinite-canvas 用的是 (^|\s)@,这里放宽成 @([^\s@]*)$, 「把@」「中间@」都能直接唤出,插入位置仍按 @ 的起点算。 - 手动打完「图N」后自动补一个空格,跟 @ 选中插入的「图N 」一致, 接着写文字不会和标签粘在一起。 · 参考图 ≥10 张时「图1」可能是「图12」的前缀,此时等用户打完数字再补, 避免把「图12」拆成「图1 2」。 · 标签后面已经紧跟汉字(如「图2的」)时在标签与汉字之间插入,不影响语义。 · 越界编号(图9 而只有 2 张图)不补空格,保持纯文本。 · 组字期间(isComposing)不插空格,避免打断 IME 的拼音串。 - 真机验证 artifacts/prompt-refs/at-check.sh: 把@ / 中间@ / @ / 已有文字后面@ 四种都能唤出候选; 用图1 → 用图1 ;用图2的 → 用图2 的;用图9 不动;@城市 只剩图2。e510d0d -
画图页提示词支持「图N」引用参考图:输入框内直接显示缩略图、可点开大图、可用 @ 唤出候选
xiaolongmr- PromptComposerTextarea 新增 referenceTokens:高亮层把命中的「图1」「图2」原地画成缩略图。 外层 inline-block 用 visibility:hidden 的文字占位、内层绝对定位铺满那一格,所以缩略图 不改变文本流里的宽高,多行混排时光标也不会错位(复用 $技能 已有的镜像层机制)。 - 缩略图可点击看大图(复用 ImageLightbox);mousedown 阻止默认行为,点击不抢输入框焦点与光标。 - 新增 @ 唤出候选:输入 @ 后在光标处弹出列表(缩略图 + 图N + 文件名),上下键选择、 回车插入、Esc 或点击外部关闭;光标坐标用镜像 div 量算,菜单会按空间自动向上翻。 - 退格 / 删除把「图N」按整体删掉(含可选的 @ 和尾随空格),不会删一半留下孤零零的「图」。 - 输入法组字期间临时关掉高亮层:高亮生效时 textarea 文字是透明的,不关掉中文打字会看不见。 - mention 与选中项的真值放在 ref:textarea 光标一动 React 会补发 onSelect, 只认 state 会让键盘选中的项在与按键同一批事件里被打回第一项。 - 画图页与批量生图页的输入框都接上了(批量页是画图页的副本,保持同步)。0d06d34 -
批量生图页:图池默认带到每一条、每条可自传参考图、行级模型与比例改用输入框同款菜单
xiaolongmr- 输入框上传的参考图进「图池」,提交时默认带到每一条提示词;参考图条上方加一句说明。 - 每条提示词可以单独上传自己的参考图(与图池合并,单条合计上限 16 张), 行内显示缩略图 + 常显的删除角标;列表行用角标显示本条自带几张。 - 行级「模型 / 比例」不再用原生 select,抽出 BatchParamMenu 复用输入框工具栏 那套「胶囊 + ChevronDown + fixed 浮层菜单」的样式与定位逻辑: 第一项固定是「默认 · 全局值」,未覆盖时值用浅色、覆盖后用深色加粗; 同一时刻只开一个菜单,外部点击关闭。 - 换模型时清掉该条的比例覆盖(第三方模型各自支持的比例不同,旧值可能不适用)。 - 每条自己的参考图用 ref 记录上传目标,避免点按钮与 change 之间拿到陈旧 state。06d53b6 -
批量生图页改版:提示词列表移到输入框上方、支持分隔符与 xlsx 导入
xiaolongmr- 布局重构:不再把多行编辑器塞进输入框,改成「列表在上、原输入框编辑选中项」—— 点列表里任意一条,输入框就显示并编辑那一条(原来输入框的内容会在进入批量模式时带进第 1 条) - 每条独立设置平铺出来:参考图、张数、模型、比例直接可见可改(不再藏在「参数」展开里); 改过之后旁边出现「恢复跟全局」用来清掉行级覆盖 - 分隔符:默认 ----,可在批量区自定义;「拆分输入框」把当前这条按分隔符拆成多条; 批量模式下粘贴含分隔符的内容也会自动拆 - 导入 xlsx / xls / csv(SheetJS):读各工作表第一列的非空单元格,跳过「提示词 / prompt」 这类表头,单元格内还能再按分隔符拆;导入结果追加进列表 - 修两个 bug: ① 追加条目改用函数式 setState —— 否则拆分时会把同一批次里刚改好的那条顶回原文; ② 导入时不能提前把 input.value = "" —— 会让已拿到的 File 变成不可读(NotReadableError) - 依赖:新增 xlsx(SheetJS)db2e2ca -
新增批量生图页:画图页副本 + 多条目编辑器 + 并发 10 一起生成
xiaolongmr- web/src/app/batch/:整页复制画图页(page.tsx + 5 个组件),批量能力只做在副本上, 不动画图页本身 - 输入卡工具条新增「批量」入口(batch-toggle),点开后同一张卡原地展开为多行编辑器: 每行一条提示词,行内独立选参考图(不选 = 纯文生图)、独立张数、按需覆盖参数; 右侧显示「预计 X 积分 / N 条 · 共 M 张 · 同时 10 条」 - 队列由「会话级串行」改为「条目级并发池」:单条执行逻辑抽成 executeTurn, runConversationQueue 改为调度器,按 BATCH_TURN_CONCURRENCY(10) 同时拉起多条; 单条提交时只拉起一个 worker,行为与改造前一致 - 额度预检仍按总张数走原有逻辑;提交后清空编辑器并退出批量模式,结果排进同一会话消息流 - 导航:config.py 默认导航 + top-nav 图标加「批量生图」;app-shell 让 /batch 复用画图页布局 - 并发数先硬编码为 10,后台配置项留待后续d7f06c8 -
撤回画图页内的批量生图,改为后续独立页面承载
xiaolongmr用户决定不在画图页里做批量(不新增页签/原地展开),改为新页面方案。 代码回到 dec77578 之前的状态: - image-composer.tsx / page.tsx 完全还原,批量入口、多条目编辑器、 handleBatchSubmit 全部移除,画图页输入区回到原来的单张形态 - 保留 docs/批量生图-方案.md(设计文档,新页面继续沿用第 8 节已确认的需求)253670c -
画图页批量生图前端:一个入口 + 原地展开的多行编辑器
xiaolongmr- image-composer.tsx:输入卡工具条内新增批量入口(data-testid=batch-toggle),点开后同一张卡 原地展开成多行编辑器(不是新页签、不新增标签)——每行 = 提示词 + 参考图 + 张数 + 参数。 - page.tsx:handleBatchSubmit —— 每行展开成 N 个独立单图任务追加到当前会话,复用现有队列, 后端 0 改动;额度预估按总张数算,不足时走原有充值提示。 - docs/批量生图-方案.md:补第 8 节(需求定稿:参考图与张数无关、不选参考图 = 纯文生图、 结果沿用画图页消息流、不做批次聚合卡片)。 - 按用户要求先只做前端样式与流程,服务端批次模型(第二期)未开始。dec7757 -
生图失败:账号配额耗尽当场出池并换号,失败卡片收掉「查看官网对话」
xiaolongmr上游「你已达到 Free 套餐的图像生成请求上限」这类只回文字、本轮没生图的终局答复, 以前被一律当成 content_policy_violation 抛给用户:账号留在池子里、本地配额对免费号是 「未知」算不到 0 → 后续每个请求都再挑中它,每个用户都吃一次同样的报错。 - conversation.py:新增 is_image_quota_exhausted_message()(中/英文原话)→ 命中时 code=image_quota_exhausted(429/rate_limit_error)、can_view_official=False;号池层 换号重试(预算 max(2, image_poll_max_attempts),本机该配置是 1,直接用等于零换号)。 - account_service.py:新增 mark_image_quota_exhausted() —— 当场置「限流 / quota=0 / image_quota_unknown=False」,由既有 account-limited-watcher 远程复核后自动回池。 - 号池被这类账号掏空时仍抛内部英文 no available image quota(站长按这串配了报错文案规则)。 - 前端:StoredImage.canViewOfficial ← task.can_view_official(page.tsx 三处映射 + 变更检测, image-results.tsx 按钮条件加 canViewOfficial !== false;老记录没这字段 = 保持旧行为)。 - 测试:test_image_upstream_note.py +8(配额识别、号池分类、换号拿到图、整池掏空仍报错、 端到端落库断言 can_view_official is False);test_account_image_capabilities.py +2。 全量 pytest 20 failed / 954 passed,FAILED 清单与基线 full-test-6.log 逐行一致。1d719cf -
报错文案:新增「规则测试」,并把「未匹配兜底」开关真正落地
xiaolongmr- 设置页「报错文案」新增规则测试:粘一条报错原文,实时给出「命不命中 / 命中第几条 / 前台最终显示什么」。 匹配口径逐条对齐后端 translate:任一关键词命中即中(不分大小写)、按顺序取第一条;停用、 关键词短于 2 字、缺大白话的规则不生效但会写明原因(可一键启用 / 跳转修改);命中多条会提示 只取第一条。测的是当前编辑中的规则(未保存也算),改一条试一条再保存。 - error_message_service.translate 落地「未匹配时报错也兜底成通用文案」开关(此前只在配置里存取、 没有任何代码消费):未命中且开关开 → FALLBACK_DISPLAY「操作失败,请稍后重试」;原文仍记入 「未配置报错」台账。默认关,本机行为不变。 - 测试:test_error_message_service.py +6(兜底两态、命中优先于兜底、停用规则在兜底下也走兜底、 空文案、开关读 config)→ 48 passed。8d002eb -
撤回批量生图功能(48b1e94a)
xiaolongmr用户决定暂不加该功能,代码回到 48b1e94a 之前的状态: - image-composer.tsx / page.tsx / prompt-composer.tsx 完全还原, 不再有「批量」入口、多行编辑器与 handleBatchSubmit - 保留 docs/批量生图-方案.md(设计文档,不影响构建与运行)1b90ec4 -
画图页新增批量生图:一个入口 + 原地展开的多行编辑器
xiaolongmr- image-composer: 工具条新增「批量」入口,同一张输入卡原地展开为多行 提示词编辑器(行号 / 行内张数 stepper / @@N 语法 / # 注释 / 回车新增 行 / 粘贴多行自动拆分 / 逐行解析状态点);批量态复用现有参数 chip, 右侧显示「预计 X 积分 + N 行 · 共 M 张 · 忽略 K 行」,提交后自动收起 回单张模式,不新增页面或页签 - page: handleBatchSubmit 按总张数做积分/号池预检后,每行展开为一个 queued turn 交给现有会话队列顺序执行,结果沿用现有消息流渲染 - prompt-composer: SubmitButton 支持 testId,便于真机验证48b1e94 -
前端撤销存量用户的昵称留空处理,弹窗留空只针对新注册用户
xiaolongmr- 撤回 nicknameDraftValue:老用户打开个人资料弹窗仍预填现有昵称(名字与展示均不动) - image/page.tsx、top-nav.tsx 恢复为 profile.name || "" 原逻辑 - 只保留后端新注册分支留空 + _normalize_item 空名豁免(新用户弹窗天然为空) - 空名展示兜底(dashboard Top 榜、卡密兑换人)仅影响新注册的空名用户315e369 -
微信新注册用户不再预置「微信用户 xxxx」内置昵称
xiaolongmr- auth_service: 新注册微信用户 name 留空;_normalize_item 对带 wechat_openid 的记录保留空名,避免被兜底成内置默认名 - 前端昵称弹窗初始值改为留空(新增 nicknameDraftValue),存量 临时名用户也不会再被预填 - dashboard Top 榜、卡密兑换人展示补空名兜底722b35a -
在线人数改为全站心跳:覆盖所有页面 + 关闭页面立即下线
xiaolongmr2c2d0e1 -
积分消耗统计:用量流水表 + 看板筛选/趋势/模型明细/Top 用户
xiaolongmr5b273a6 -
实时在线人数:画图页纯文字展示 + 管理员数据看板
xiaolongmr7ef525a -
修复:「生成后清理官网对话」开启时取证静默失效
xiaolongmr真机现场(HF zlcy/li):该站开着「生成后清理官网对话」,出图成功后走清理分支 直接隐藏会话(隐藏 == 官方删除,分享链接必 404),且这条路径完全绕过取证登记 (其 finally 分支里 `and not config.cleanup_shared_conversations` 早已把它排除)。 结果:取证永不登记 → 用户点「查看官网对话」只能走兜底登记(拿不到账号信息)→ 一直报「上游账号已不可用」。另两个站没开这个开关,所以正常。 - conversation.py 清理分支:取证开启时改为登记进保留台账、隐藏推迟到保留期结束由 _release 统一执行(连隐藏带删链接),清理意图只是延后;登记带上热 token。 - share_evidence_service._release:没有链接且完全没有账号信息(修复前的老记录/兜底 登记)→ 直接结案 released(unreachable),不再永久 orphan 退避刷日志;有活链接仍 保持重试。 - 设置页「共享号池设置」文案:取证开启时提示隐藏会推迟到保留期结束。 测试:新增 protocol 生命周期用例(清理+取证 → 不隐藏、登记带 token)+ 回收结案 两条用例;全量 895 passed / 20 failed 与基线逐行 diff 一致(零回归);tsc/eslint 干净。81b3985 -
官网来源取证 + 生图终局判定 + 对话卡片渲染
xiaolongmr- 官网来源取证:每张结果图可生成 chatgpt.com 官方匿名分享链接自证「确实是官网出的图」; 出图即固化(独立线程,不占积分/额度/并发槽),到期按保留时长自动回收并隐藏上游会话 - 生图失败判定:识别内容策略拒绝(is_error 终局文本)不再白等到超时;同一张图按 id 去重, 修 n=1 出两张重复图;失败卡片补「ChatGPT 官网原话」与「查看官网」 - 提示词比例追加:默认开启,仅用户主动选比例时追加(智能比例不受影响) - 对话渲染:app_block 裸 JSON 转 html 围栏、官网 DIL 卡片/问卷降级渲染、多题勾选统一作答、 思考摘要不展示 - 内容审核:良性复合词白名单(灵感爆炸/色彩爆炸/爆炸头等),修设计海报误拦 测试:全量 888 passed / 20 failed(与基线一致,零新增);tsc、eslint、next build 均干净2aabbd0
4 days ago
-
报错文案映射与 AI 归纳 + 上传限流换号 + Skills 批量删除
xiaolongmr后台报错文案 - 新增 error_message_service:按关键词子串(任一命中 OR、不区分大小写)把上游原始报错 映射成管理员配置的大白话,只影响前台展示,原始报错仍进后台日志。 - 未命中时记入「未配置报错」待办,并在列表里附候选关键词,便于一键建规则。 - 新增 POST /api/error-messages/summarize:粘贴报错即可让模型归纳出 「关键词 + 大白话」,模型不可用时退化为本地正则抽取。 - 提示词写入本项目上下文:匹配为任一命中语义、上游报文格式 `{接口路径} failed: status={状态码}, body={...}`、路径须带区分步骤片段、 禁止 file_id/uuid 等易变片段,避免归纳出过宽规则(如裸 /backend-api/files 会吞掉 429 限流)。 - 关键词清洗:新增 _sanitize_keyword / _strip_volatile_path / _GENERIC_TOKENS, 剔除 JSON 语法碎片(引号、花括号、冒号)与 error_code 等通用字段名。 - 三类报错出口统一走映射:协议层 error_response、生图任务、可编辑文件任务。 - 前端设置页新增「报错文案」卡片:粘贴框 + AI 归纳按钮 + 内联结果卡片 (关键词/大白话就地可改、可就地保存)、规则列表、未配置报错列表。 - 修复「点添加规则没反应」:store 拆成 coerce(编辑态,保留空行)与 normalize(保存态,丢弃无效项)两档归一化,编辑态不再误丢刚加的空行。 - 修复「归纳结果看不见」:高亮延长到 6 秒并加绿底/绿边/徽标,结果面板就地可操作。 生图上传限流换号 - 新增 is_account_scoped_upload_error:识别 upload_protection_limit_exceeded / 429 上传类失败。这类限制是单账号配额,换号几乎必成,不再当作终态失败。 - 号池因上传限流被逐个排除到池空时,给出准确原因而非笼统的「生成失败」。 - 被限流换掉的账号不触发账号清理(只加入本轮排除集合并归还并发槽)。 Skills - 新增 POST /api/admin/skills/batch-delete,一次删多个…241a123
5 days ago
-
签到积分账本与有效期 + 内容审核反绕过加固 + 签到文案配置化
xiaolongmr签到积分 - 新增 checkin_credit_remaining 真账本:仅 source=checkin 入账,仅在基础池扣减点冲减 - 新增 checkin_credit_valid_days(0=永久,>0 发放成带 expires_at 的限时券,上限 3650) - 保存设置时若该值变化,自动重算已发放的签到积分(保留各批次原节奏) - 弹窗「我的积分」底部提示:签到赠送剩余可用 N 积分,有 M 积分将于 K 天后到期,请及时使用~ 内容审核 - 繁简归一(services/_zh_t2s.py)、17 语词表、HTML实体/百分号/Unicode/Base64 变形解码 - 否定语境豁免、良性复合词、组合规则间距窗口、ASCII 词边界、弱词机制 其他 - 签到页文案(公告/弹窗/页脚/二维码)改为后台配置 checkin_content - 新增回归 test/test_checkin_credit_ledger.py44a4285
7 days ago
-
对话 复制编辑和暂停
xiaolongmr464179c
8 days ago
-
10.9
xiaolongmr8fe6561
9 days ago
-
fix: harden HF persistence and runtime workflows
xiaolongmr34f333f -
Make image poll retry attempts configurable
xiaolongmr4406451
10 days ago
-
1.07
xiaolongmr59af925 -
1
xiaolongmr6daa87a
15 days ago
-
优化
xiaolongmr4f03ac7
17 days ago
-
对话功能
xiaolongmrf644e36 -
测试
xiaolongmr263e0b9
18 days ago
-
临时修复
xiaolongmr5f89ffd