Fetching metadata from the HF Docker repository...
Oct 19 10 days ago 07:00 xiufu shijian xunhuan bei suoding de genyin: qingqiu relu bu zai xie ku xiaolongmr
堆栈证据:事件循环线程卡在
chat_room.list_direct_conversations -> require_identity
-> authenticate -> _update_items_locked -> update_auth_keys_locked
即「async 路由里同步鉴权,鉴权里同步写整张 auth_keys 表」。
三处改动:
1. authenticate 热路径零存储 IO
last_used_at 只更新内存快照并记脏,由后台线程每 30 秒批量合并落库。
事件循环再也不等待存储锁。
2. 缓存未命中也不回读存储
未知/失效 token 以前会 _reload_locked() 读全表,把事件循环拖进数据库。
现在直接返回 401,回读交给后台线程兜底(单副本下内存快照即权威)。
3. update_auth_keys_locked 只写变化的行
以前是无条件 row.data = payload,等于每次改一条都把整表标记 dirty
并逐行 UPDATE + commit。图片任务线程并发结算积分时,
SQLite 写锁被占用数百毫秒,事件循环只能排队。
附带:去掉 21 处 with self._lock: 包 _update_items_locked 的反向锁嵌套,
锁顺序统一为「存储 -> 鉴权」,消除再次 ABBA 的可能。 06:40 xiufu jiandeng yu shangdian huxiang dengdai de sizi suo; tanzhen buzai zhudong tuichu xiaolongmr
06:27 jiandeng last_used_at xiechu jieliu, bimian mei ci qingqiu zhongxie zheng zhang jian quan biao xiaolongmr
06:05 yongjiu shibai de fenxiang jilu zhijie tuo li duilie, bu zai rang shangyou chongshi xiaolongmr
05:56 shangyou 401 403 zhongzhi chongshi, bimian chongshi fengbao tuo kua rongqi xiaolongmr
Oct 17 12 days ago 08:30 zidong shibie fumian tishici quduan, wu xu shoudong jia fangxing duanyu xiaolongmr
08:18 zuhe guize gai wei tong ju pipei; fangxing duanyu he changjing kaiguan ke zai shezhi ye peizhi xiaolongmr
08:00 fuzhuang silie bu zai bei pan wei xiexing; bufang fuzhuang yujing wushang xiaolongmr
Oct 16 13 days ago 08:10 houtai xintiao jiang pin dao 50s, fangkuan zaixian chuangkou dao 120s xiaolongmr
presence 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。 Oct 15 14 days ago 15:00 聊天室:修复置顶 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 全绿。已清… 14:14 聊天室:管理员置顶公告 + 修复私聊收不到/回不了 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 项失败)。 13:11 区分「上游 CDN 拦截」与「token 失效」,修复导入账号报 403 xiaolongmr
导入账号时报 /backend-api/accounts/check failed: HTTP 403。实测确认这不是
账号问题:同一个 token 本地直连 200,HF 容器内 403;补 sentinel token 后本地
依然 200,说明与请求内容无关,只与出口 IP 有关(容器出口被 Cloudflare 拦,
响应体是 HTML 拦截页,与此前 share_evidence_release_failed 的 403 形态一致)。
原代码把任何非 401 失败都当成单纯刷新失败,账号虽未被判死,但错误文案会让人
误以为号坏了。
改动:
- openai_backend_api:新增 UpstreamBlockedError;_get_default_account() 增加
CDN 拦截识别(content-type/body 形态)与一次退避重试,403+HTML 抛
UpstreamBlockedError,403+JSON 仍抛 RuntimeError。
- account_service.refresh_accounts():单独捕获 UpstreamBlockedError,账号保持
原样、不计失效,错误文案改为可读的「上游 CDN 拦截…非账号问题」,新增
blocked 计数随结果返回。
- api/accounts.py:导入响应透出 blocked 字段。
- api/system.py:新增管理员诊断接口 POST /api/upstream/probe,可从容器出口
直连指定路由并回报 status / cf-ray / body / 是否 CF 拦截页。 10:54 生图求解增加进程内 V8 兜底,单容器部署无需外部 solver xiaolongmr
上游 chatgpt.com 只接受在真实页面上下文里算出的 Turnstile,缺失或质量不够时
f/conversation 返回伪装成 404 的 {"detail":"Model not found"}。此前唯一可行路线是
外部 sentinel_solver 服务(常驻无头 Chromium),但 HF Space 等单容器环境跑不了
第二个容器,导致线上生图必然 404。
本次移植 py-mini-racer 路线,在进程内嵌 V8 直接跑上游真实 sentinel SDK:
- 新增 utils/sentinel_v8.py:加载 assets/sentinel/{sdk.js,shims.js},
按指纹缓存 V8 上下文,全局锁保证不可跨线程并发
- 新增 assets/sentinel/{sdk.js,shims.js}:上游 SDK 与浏览器环境 shim,
sdk.js 构建时打补丁暴露内部求解函数(__reg / __solve_dx)
- services/sentinel_solver_client.py:求解优先级改为
外部服务 → 进程内 V8 → 旧手写 VM;solver_user_agent() 在外部服务
探测不到 UA 时回落内置 Chromium UA,避免与 V8 shim 环境不一致
- pyproject.toml:新增 mini-racer>=0.14.1(导入名仍是 py_mini_racer)
- Dockerfile:COPY assets 进镜像
实测:solver_url 置空时 V8 自动接管,算出 1076 字符 turnstile token,
与外部浏览器路线的 1200 字符量级一致;两条路线在账号层面均返回 404,
说明该 404 与被测账号本身相关,与求解方式无关。
已知边界:V8 目前只覆盖 Turnstile(dx),so 仍需外部求解服务。 07:31 聊天室:头像回退微信头像、复用画图页输入框、撤回删除、布局收口 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 会与之相… 06:41 新增聊天室页面:登录用户群聊 xiaolongmr
- 后端:services/chat_room_service.py(SQLite 只追加存储,经镜像 runtime_file 持久化)+ api/chat_room.py(消息增删查 / 汇总接口,均需登录)
- 前端:/chat-room 页面,3s 轮询增量拉取、乐观发送、回车发送、500 字上限、自动滚底、日期分隔与角色徽章
- 导航:三套角色导航均插入「聊天室」(对话之后),含一次性迁移 05:11 放开 chrome150 指纹白名单 xiaolongmr
社区实测 chatgpt.com 对 chrome146 的 TLS 指纹仍可能判为低可信,对话接口
返回伪装成 404 的 "Model not found",chrome150 才通过(curl_cffi 0.16.3 已支持
chrome150,可在本机 __version__ 与 BrowserTypeLiteral 里确认)。
_SUPPORTED_CHROME_MAJORS 是 _canonical_browser_profile 判断「指纹是否受支持」
的白名单:major 不在集合内会直接落到 fallback,用回 DEFAULT_CHATGPT_IMPERSONATE。
此前实测传入 impersonate="chrome150" 实际生效仍是 chrome146,原因就是 150 不在
白名单。补上 150 后,显式指定 chrome150 才能真正生效。
刻意不改 DEFAULT_CHATGPT_IMPERSONATE:该值参与 fp 计算,_client_context_changed
以 original["fp"] != normalized["fp"] 判定迁移,改默认值会让所有存量账号 fp 变化
并触发一次全量重写。默认行为保持 chrome146 不变,升 150 待拿到干净账号后 A/B 验证。 04:59 补齐 sentinel SO token 并让求解服务支持指定 Chrome 版本 xiaolongmr
排查 2026-10-14 生图 404:定位到 404 实际发生在 /backend-api/f/conversation,
chat-requirements 的 prepare/finalize 两步本身可通、Turnstile 也能解出。
- prepare 响应里 so 也是 required(collector_dx + snapshot_dx),
chatgpt.com 对缺 SO token 的对话请求返回伪装成 404 的 "Model not found"。
- sentinel_solver_client 新增 solve_so(),调用求解服务 /v1/so 端点。
- _get_chat_requirements 解出 SO token 并随 finalize 提交,落进 ChatRequirements.so_token,
由 _image_headers / _conversation_headers 带成 OpenAI-Sentinel-SO-Token 头。
- sentinel_solver/app.py 支持 SENTINEL_SOLVER_CHROME_PATH:优先用指定 Chrome 可执行文件
(默认指向 chrome-for-testing 153.0.8010.12,与 Playwright chromium 1243 对齐),
找不到时回退 channel="chromium"。
注:本地实测仍 404,根因指向出口 IP 归属 CN(非代码问题),详见当日工作日志。 03:16 借鉴 MEIZU16 把 chat-requirements 改为 prepare/finalize 两步流程修复 404 xiaolongmr
chatgpt.com 自 2026-10-14 起,旧的「单步」chat-requirements 算出的 token 被判为低可信,
对话/生图接口统一返回伪装成 404 的 "Model not found"。
改动:
- 把 _get_chat_requirements 从单步 POST 改为 prepare + finalize 两步:先 prepare 拿 challenge
参数(proofofwork / turnstile / prepare_token),用真实浏览器(sentinel_solver 服务)解出
Turnstile,再 finalize 换回真正可用的 token。复用既有 _build_requirements 算
proofofwork/turnstile,文本对话与生图链路的所有调用方(2201/2251/2441/2846)自动生效。
- sentinel_solver/app.py 同步上游最新的 SENTINEL_SOLVER_TIMEZONE 配置(页面时区需与出口
IP 所在地一致,利于过 Cloudflare 校验),含 docstring、环境变量、上下文 timezone_id 与
/health 状态输出。
生效前提:必须实际运行 sentinel_solver 服务并配置 CHATGPT2API_SENTINEL_SOLVER_URL,
否则回落本地兜底求解器仍会 404。 02:46 借鉴 MEIZU16/chatgpt2api 完整方案修复 404:接入 sentinel 求解服务 xiaolongmr
404 根因(issue #416):2026-10-14 起 chatgpt.com 只接受在真实页面算出的
Turnstile/SO token,纯 Python 模拟被拒(403 或伪装成 404 的 "Model not found")。
TLS 升 chrome146 只能解决「低可信」那一截,强制要求 Turnstile 时必须靠真实浏览器。
- 新增 sentinel_solver/:常驻无头 Chromium 的 chatgpt.com 页面,通过 HTTP 替主服务
算 Turnstile/SO token(playwright + playwright-stealth,移植官方挑战 VM)
- 新增 services/sentinel_solver_client.py:后端调用求解服务;未配置或失败时回落本地
utils.turnstile 兜底(已跟不上新版,仅兜底)
- services/openai_backend_api.py:turnstile 改走 solve_turnstile;_sentinel_user_agent()
回落 solver_user_agent(),保证 requirements/proof token 的 UA 与求解页一致
- services/config.py:sentinel_solver_url / sentinel_solver_key(env 或 config.json)
- docker-compose.yml:加 sentinel-solver 服务,主服务注入 CHATGPT2API_SENTINEL_SOLVER_URL
生效前提:需实际运行求解服务并配置 CHATGPT2API_SENTINEL_SOLVER_URL,否则仍回落本地兜底。 02:31 修复 2026-10-14 后 /backend-api/f/conversation 伪装成 404 的报错 xiaolongmr
chatgpt.com 自 2026-10-14 起对低质量 sentinel 请求返回伪装成 404 的
"Model not found":chrome110 的 TLS 指纹被判低可信,且图片链路必须带齐
Turnstile/SO 头。对齐上游修复:
- TLS impersonation 由 chrome110 升到 chrome146(curl_cffi>=0.13 才支持,
本机已升级到 0.16.3);账号 fp 里残留的 chrome110 等旧 impersonate 统一
清除后回落 chrome146,保证 TLS 与 UA 一致
- _image_headers 补上 OpenAI-Sentinel-Turnstile-Token / OpenAI-Sentinel-SO-Token
(之前只有 Proof-Token),404 正好出在图片接口 /backend-api/f/conversation
- 新增 _sentinel_user_agent(),POW/legacy token 里的 UA 收敛到与发请求浏览器
一致(预留接入 sentinel 求解服务的入口) Oct 14 15 days ago 15:47 新增批量生图页:画图页副本 + 多条目编辑器 + 并发 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,后台配置项留待后续 15:04 生图失败:账号配额耗尽当场出池并换号,失败卡片收掉「查看官网对话」 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 逐行一致。 15:04 报错文案:新增「规则测试」,并把「未匹配兜底」开关真正落地 xiaolongmr
- 设置页「报错文案」新增规则测试:粘一条报错原文,实时给出「命不命中 / 命中第几条 / 前台最终显示什么」。
匹配口径逐条对齐后端 translate:任一关键词命中即中(不分大小写)、按顺序取第一条;停用、
关键词短于 2 字、缺大白话的规则不生效但会写明原因(可一键启用 / 跳转修改);命中多条会提示
只取第一条。测的是当前编辑中的规则(未保存也算),改一条试一条再保存。
- error_message_service.translate 落地「未匹配时报错也兜底成通用文案」开关(此前只在配置里存取、
没有任何代码消费):未命中且开关开 → FALLBACK_DISPLAY「操作失败,请稍后重试」;原文仍记入
「未配置报错」台账。默认关,本机行为不变。
- 测试:test_error_message_service.py +6(兜底两态、命中优先于兜底、停用规则在兜底下也走兜底、
空文案、开关读 config)→ 48 passed。 10:30 微信新注册用户不再预置「微信用户 xxxx」内置昵称 xiaolongmr
- auth_service: 新注册微信用户 name 留空;_normalize_item 对带
wechat_openid 的记录保留空名,避免被兜底成内置默认名
- 前端昵称弹窗初始值改为留空(新增 nicknameDraftValue),存量
临时名用户也不会再被预填
- dashboard Top 榜、卡密兑换人展示补空名兜底 09:44 用量流水库接入存储桶快照持久化(与账号/卡密库同一机制) xiaolongmr
09:30 用量流水库改跟随 DATA_DIR,支持持久卷/环境变量指定路径 xiaolongmr
09:22 内容审核:豁免肩颈/锁骨/四肢『裸露』正常部位描写 xiaolongmr
08:35 在线人数改为全站心跳:覆盖所有页面 + 关闭页面立即下线 xiaolongmr
08:04 积分消耗统计:用量流水表 + 看板筛选/趋势/模型明细/Top 用户 xiaolongmr
07:44 实时在线人数:画图页纯文字展示 + 管理员数据看板 xiaolongmr
01:59 修复:「生成后清理官网对话」开启时取证静默失效 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 干净。 01:37 取证修复:台账固化出图热 token,账号被删也能生成/回收分享链接 xiaolongmr
- register_conversation 新增 access_token:出图那一刻把上游 token 存进台账。
之前只记邮箱、事后按邮箱反查号池,账号被删出号池/轮换 token 后反查落空,
前端表现为「这条会话所属的上游账号已不可用」(HF 部署后复现)。
- _resolve_access_token 顺序:账号池按邮箱反查(拿最新轮换 token)→ 登记
时固化的热 token 兜底;token 只落服务端台账,describe() 白名单不回前端。
- 区分两类失败文案:登记时无账号信息 vs 账号已不在池中,并加
share_evidence_account_unresolved 诊断日志。
- 回收路径(_release)同样吃到热 token 兜底。
测试:test_share_evidence +4(热 token 兜底/池优先/补登 token/无信息文案),
全量 888 passed 零新增失败(4 个 *_http 集成项为后端未启动所致,带后端重跑全过)。 01:21 官网来源取证 + 生图终局判定 + 对话卡片渲染 xiaolongmr
- 官网来源取证:每张结果图可生成 chatgpt.com 官方匿名分享链接自证「确实是官网出的图」;
出图即固化(独立线程,不占积分/额度/并发槽),到期按保留时长自动回收并隐藏上游会话
- 生图失败判定:识别内容策略拒绝(is_error 终局文本)不再白等到超时;同一张图按 id 去重,
修 n=1 出两张重复图;失败卡片补「ChatGPT 官网原话」与「查看官网」
- 提示词比例追加:默认开启,仅用户主动选比例时追加(智能比例不受影响)
- 对话渲染:app_block 裸 JSON 转 html 围栏、官网 DIL 卡片/问卷降级渲染、多题勾选统一作答、
思考摘要不展示
- 内容审核:良性复合词白名单(灵感爆炸/色彩爆炸/爆炸头等),修设计海报误拦
测试:全量 888 passed / 20 failed(与基线一致,零新增);tsc、eslint、next build 均干净 Oct 13 16 days ago 07:19 报错文案映射与 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,一次删多个… Oct 12 17 days ago 15:56 签到积分账本与有效期 + 内容审核反绕过加固 + 签到文案配置化 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.py Oct 10 19 days ago 23:38 对话 复制编辑和暂停 xiaolongmr
09:15 10.10 xiaolongmr
Oct 9 20 days ago 02:34 10.9 xiaolongmr
Oct 8 21 days ago 07:19 fix: avoid integrity scanning task database on bucket startup xiaolongmr
06:56 fix: harden HF persistence and runtime workflows xiaolongmr
04:10 Make image poll retry attempts configurable xiaolongmr
03:24 Handle runtime SQLite readonly failures xiaolongmr
Oct 7 22 days ago 12:00 1.07 xiaolongmr
05:45 1 xiaolongmr
Oct 2 27 days ago 08:53 优化 xiaolongmr
Sep 30 29 days ago 05:07 测试 xiaolongmr
Sep 28 17:10 添加chat xiaolongmr
08:43 编辑功能(测试) xiaolongmr
07:56 添加编辑 xiaolongmr
Sep 13 17:59 优化 xiaolongmr