Skip to content

Releases: wc985732-lang/qq-live-digest

v0.5.0 — 界面与主题(卡片瘦身 + 深/浅双主题)

Choose a tag to compare

@wc985732-lang wc985732-lang released this 09 Oct 16:13

[0.5.0] - 2026-10-10

界面

  • 卡片瘦身(headless Edge 实测,390×844 视口 DPR2,55 条待办):卡片内的
    「详细要求 / 查看完整原文 / 纠错」原本各占一整行(296×18px 纯文字、零内边距,手机实测相邻间距
    仅 7px,既容易误触、又把卡片撑得老高),现在并成一行胶囊按钮(详细 / 原文 / 纠错,
    min-height:44px,短标签给眼睛看、完整名称放 aria-label + title 给读屏)。
    单卡高度 194px → 129px,55 条待办整页 10 830px → 7 837px,首屏可见卡片 3 张 → 4 张。
    开关补上按下态(:active)与键盘焦点环(:focus-visible)——此前全局关闭了系统点击高亮又没有按下反馈。
  • 「查看完整原文」展开后正文限高 45vh 并内部滚动(overscroll-behavior:contain),
    不再把卡片从约 130px 撑到约 470px、挤走后续待办;展开时标题切换为「收起」。
  • 深/浅双主题:配色改为语义 token(--bg / --bg-top / --glass-* / --card / --card-2 / --line / --text / --muted / --dim / --accent / --tint-* / --hero-* …),深色是 :root 默认值,
    浅色只覆盖同名 token。设置页新增「外观:跟随系统 / 浅色 / 深色」,选择存 localStorage,
    <head> 里的内联脚本在首帧前落到 data-theme(不会先画一帧深色再切),跟随系统
    prefers-color-scheme 变化,并同步 meta[name=theme-color]、iOS 状态栏样式与 manifest 颜色。
    原深色配色正文对卡片仅 3.53:1、次级 2.76:1(均低于 WCAG AA 4.5:1),重排后为
    14.55 / 7.80 / 5.02(浅色 16.90 / 5.98 / 4.51)。
  • 群名胶囊并入卡片顶部信息行(原来单独占一行,约 29px/卡),不再每张卡多一行。
  • 勾选圆点本体只有 29px,加一层透明子元素把命中区撑到 45px(视觉与位置不变)。
  • 清理设计 token:删掉已无引用的 --ink-on-solid、--urgent,并替换掉 var(--surface) /
    var(--grad) 等旧变量残留(未定义的 var() 会被浏览器当无效值静默丢弃)。

修复

  • 待办台卡片里的「已逾期」红胶囊是重复信息(同一条任务的截止时间胶囊已经写着「…已过」且同色),
    而且会把卡片顶部信息行挤到第二行(+23px/卡)——已删除。
  • 跨天(非今天)的过期截止时间此前显示成「09-28 18:00 截止」,读起来像还没到点;
    改为「09-28 18:00 已过」,与 overdue 标志一致。
  • 修正 qq_live_digest/doctor.py 中 run_checks() 列表里一行的缩进层级(纯排版,无行为变化)。

测试

  • 新增回归测试:待办台重启会沿用已生成的 token、不轮换(轮换会让已保存的带 token 链接 / PWA 静默失效)。
  • 新增回归测试:锁定待办台卡片开关的 44px 命中区、勾选圆点的 45px 命中区、原文限高与展开态文案切换。
  • 新增回归测试:跨天过期截止时间必须显示「已过」,且不再渲染重复的「已逾期」胶囊。
  • 新增回归测试:浅色 token 块、data-theme 引导脚本、设置页三态外观开关与 manifest 颜色一致;
    同时禁止 var(--surface) / var(--grad) 之类旧 token 引用回流。

截图

深色 · 改动前后对比

深色 · 改动前后对比

浅色主题 + 设置页「外观」开关

浅色主题 + 设置页「外观」开关

浅色主题(待办台主视图)

浅色主题(待办台主视图)

截图由 headless Edge 在本机跑真实服务渲染(390×844 视口、DPR2;数据是程序生成的虚构示例)。

升级说明

无破坏性变更,也无新增配置项:pip install -r requirements.txt 后按原方式重启即可。
主题偏好只存在浏览器 localStorage,服务端不落任何新字段,PWA 缓存策略也未变。

v0.4.1 — 安全加固(审计修复)

Choose a tag to compare

@wc985732-lang wc985732-lang released this 09 Oct 14:26

v0.4.1 — 安全加固

对 v0.3.1 → v0.4.0 的新增面做了一轮安全 / 正确性审计,本版修完全部问题并补齐回归测试。含两处破坏性行为变更,升级前请先看「兼容性」。

安全

  • 邮件推送(SMTP)证书校验:走 587 + STARTTLS 时未传 TLS 上下文,smtplib 默认 CERT_NONE(既不校验证书也不校验主机名),账号口令与摘要正文可被中间人窃听。现在 SMTP_SSL 与 starttls() 都使用 ssl.create_default_context()。
  • 待办台鉴权反转 + 缺 CSRF 校验:过去 QQ_DIGEST_WEB_HOST 为回环地址且未配 token 时不生成 token(本机部署等于免鉴权),写请求也没有跨站校验。现在无论监听哪里都会生成 token 并落库;写请求校验 Origin(跨站返回 403);页面拿到 token 后立即从地址栏 / 历史 / Referer 移除。
  • 归档待办泄露:conflicts、ICS 导出、/api/deadlines、/api/todos 过去只排除 done,被忽略 / 过期归档的待办仍会出现在冲突提醒与日历里。现新增统一的任务状态口径,日历与冲突一律跳过归档态。
  • OneBot 鉴权边界:未设上报 token 时不再允许监听非回环地址(这种配置等于局域网内任何人都能伪造群消息),接收器会直接拒绝启动。
  • token 比较改为恒定时间(hmac.compare_digest),消除逐字符比较的计时侧信道。
  • 搜索的 LIKE 通配符注入:search_messages 未转义 % / _,传 % 即等于扫全库;现在转义并显式 ESCAPE。
  • 推送凭据遮蔽:Telegram 错误信息遮蔽 bot_token;Ntfy 在非 https 端点下丢弃 NTFY_TOKEN。

修复

  • mcp.call_tool 遇到未知 Tool 不再抛 KeyError,改为返回 isError 结果。
  • ICS 续行按 74 字节折行(含前导空格不超过 RFC 5545 的 75 字节)。
  • 事件合并:两侧都没有日期 / 来源 / 截止硬锚点时收紧判据,减少「换个说法的闲聊」被误合并。
  • doctor 口径与本次政策对齐:待办台「对外 + 未显式配 token」由 FAIL 降为 WARN;OneBot「对外 + 无 token」由 WARN 升为 FAIL。
  • 收敛重复实现(掩码 / 任务状态 / 整数限幅各收敛为一份);REST 的坏参数不再 500;logging_setup 不再残留未关闭的文件句柄。

兼容性

两处破坏性行为变更:

  1. 待办台现在总是需要 token。 过去 QQ_DIGEST_WEB_HOST 为回环地址且未设 QQ_DIGEST_WEB_TOKEN 时页面不鉴权;现在无论监听哪里都会生成 token 并存入 SQLite meta 表。用 python main.py tasks 打印带 token 的访问地址;对外部署建议用 QQ_DIGEST_WEB_TOKEN 显式固定。
  2. OneBot 未设 token 时不再监听非回环地址。 QQ_DIGEST_ONEBOT_HOST 不是 127.0.0.1 / localhost / ::1 且 QQ_DIGEST_ONEBOT_TOKEN 为空时,接收器拒绝启动。请补 token,或改回只监听回环。

另有 doctor 的退出码语义变化(见「修复」末条),若有脚本依赖该退出码请相应调整。

测试

603 个用例通过(较 v0.4.0 的 591 增加 12 例,含 11 个安全 / 边界回归测试)。另做了一次真实冒烟:回环自动生成 token 并落库、无 token → 401 / 有 token → 200、跨站写 → 403、0.0.0.0 无 token 拒启、dismissed 待办不进冲突与日历。

完整改动:v0.4.0...v0.4.1

v0.4.0 — Phase 2 信息中枢(A11 / A15 / A1 / A2 / A13 / A12 / A14 / A16 / A22)

Choose a tag to compare

@wc985732-lang wc985732-lang released this 09 Oct 12:45

v0.4.0 — Phase 2 信息中枢

Phase 2「产品化 / 信息中枢」的九项全部落地,Phase 2 验收清单至此全部 ✅。无破坏性变更。

亮点

  • 事件级跨群聚合(A11):把同一事件在多个群的转发合成一条(结构化事件键=对象+动作+时间+截止+来源),误合并可用 python main.py events --split <事件键> 覆盖拆分。默认关闭(QQ_DIGEST_EVENT_MERGE=0),打开后才改变推送口径。
  • 只读 REST API(A15):待办台同端口提供 /api /api/notifications /api/tasks /api/deadlines /api/panel /health,X-Token / ?token= 鉴权,只发 SELECT。
  • MCP 接口(A1 只读 + A2 确认后可写待办):python main.py mcp(stdio)给 Cursor / Claude 用,现共 5 只读 + 2 可写 = 7 个 Tool。可写只碰 tasks(完成 / 新建),必须显式 confirm=true,每次调用逐次写 audit_log 审计;没有任何 QQ 发送 / 删群 / 改设置的入口。
  • ICS / 日历导出(A13):python main.py ics(别名 calendar)与 GET /api/calendar.ics 把有明确时间的待办导成 iCalendar(RFC 5545,CRLF)。只读。
  • 时间冲突检测(A12):截止时间落在同一时间窗(默认 30 分钟)的待办按组提醒,python main.py conflicts 与 GET /api/conflicts。只提醒,不擅自改任务。
  • 多端推送扩展(A14):补上 ntfy / Telegram / Discord / 企业微信(群机器人)/ 邮件(SMTP),与既有通道共用「主通道失败 → 回退其它通道」与 deliveries 去重;不配即与以前完全一致。
  • PWA 离线(A16):待办台可安装、断网仍能打开并回放最近一次的通知 / 待办(离线只读),写操作在离线时直接拦下并提示。
  • Prompt / 模型 A-B 对比(A22):python main.py ab 在同一份固定评测集上对比两套配置的准确率 / 成本 / 延迟并给出胜者。

兼容性

  • 无破坏性变更。 新功能均有开关或按需触发:A11 默认关闭、A13 / A12 只读、A14 不配即与以前一致、A16 只影响网页待办台、A22 只在显式调用时跑。
  • data/ 数据库只新增 audit_log 表(MCP 审计)与 event_splits 表(事件拆分覆盖),无迁移。

测试

591 个用例通过(较 v0.3.1 的 478 增加 113 例)。评测基线未漂移:500 条 / seed=20261008 上召回 98.8%、误报 0.5%、待办 59/59、截止 59/59、跨群去重 4/4、延迟中位 0.0 / P95 31.6 分钟 —— 与同一时刻的 v0.3.1 逐项一致(顺带修掉一处 ICS DTSTAMP 断言依赖运行机器时区的脆弱测试)。

完整改动:v0.3.1...v0.4.0

v0.3.1 — Phase 1 收尾(A9 + A32)

Choose a tag to compare

@wc985732-lang wc985732-lang released this 09 Oct 09:00

v0.3.1 — Phase 1 收尾(A9 + A32)

Phase 1「AI 可控、可测、可替换」的两条收尾项落地,Phase 1 验收清单至此全部 ✅。无破坏性变更。

亮点

  • 群级个性化策略(A9):每个群可以在全局配置之上覆盖少量开关(安静群 / 本群额外关键词 / 进摘要最低分 / 模型档 / 免打扰时段),没写的字段一律继承全局,只改一个群不会牵连别的群。配置写在 QQ_DIGEST_GROUP_POLICIES(JSON,键可以是群号或群名);python main.py groups(别名 policies,--json)逐群打印最终生效的开关与本群覆盖了哪些字段;doctor 的「群白名单」一行会提示有几个群配了策略。坏 JSON / 认不出的字段 / 非法时段只丢自己,不抛异常。
  • 消息处理可观测面板(A32):一条命令看清消息是怎么被处理的——收了多少条(含群数与最活跃的几个群)、判了多少条与过滤率、攒出多少候选(推送 / 保留 / 待确认)、调了几次模型与 token 用量、推送成功率、候选待办的人工确认情况。python main.py observe(别名 panel,--days / --json)给终端视图;待办台服务同端口提供网页版 /panel 与 /api/panel(token 与待办台相同,不新起端口),doctor 新增「可观测面板」一行。实现是 qq_live_digest/observe.py(纯聚合,只发 SELECT,不写库、不联网)。默认脱敏:群号一律掩码、不带消息正文 / 发送者 / 任何密钥,输出可直接贴出来。

口径写进 README:过滤率分母只算已决状态(待投递 / 延后未决是过程态)、推送成功率的分母不算待发、数据不足时给 0.0 而不是假装 100%。

兼容性

  • 无破坏性变更。 data/ 数据库无 schema 变更(只新增只读聚合查询)。
  • 不配 QQ_DIGEST_GROUP_POLICIES 时行为与 v0.3.0 完全一致。

测试

478 个用例通过(新增 tests/test_observe.py 21 例,含脱敏断言,全程不联网)。评测基线未漂移(500 条 / seed=20261008:召回 100%、误报 0.5%、待办与截止时间 100%、跨群去重 100%、延迟中位 0.0 / P95 31.6 分钟)。

完整改动:v0.3.0...v0.3.1

v0.3.0 — AI 可控、可测、可替换(Phase 1)

Choose a tag to compare

@wc985732-lang wc985732-lang released this 09 Oct 05:11

v0.3.0 — AI 可控、可测、可替换(Phase 1 主体)

这个版本把「大模型」从黑盒变成可核算、可解释、可替换的一层:花的钱能看清、判的理由能读懂、换供应商只改配置。

演示

亮点

  • 模型 Provider 抽象(A4):业务代码只依赖 qq_live_digest/providers.py 的 LLMProvider / LLMResult,换供应商只改配置(QQ_DIGEST_LLM_PROVIDER,none 可彻底关闭模型调用);文档见 docs/PROVIDERS.md。
  • Token / 成本统计(A5):每次模型调用落一行 llm_calls(provider / 模型 / 输入输出 token / 耗时 / 失败原因 / 是否重试 / 是否降级),python main.py llm-stats(别名 cost)给出日 / 周 / 月视图,按 QQ_DIGEST_LLM_PRICE_IN / _OUT 在展示时折算费用,改价不重写历史。
  • 置信度与可解释性(A7):每条候选给出 0–1 的 confidence 与一组人话化的触发规则(权重写在解释里),推送正文会附「为什么…(把握较高 82%)」。
  • 模型分级路由(A6):本地规则 → 轻量模型 → 高能力模型,难例判据只用确定性信号,路由原因随用量落库,llm-stats 可查「路由分布」。
  • 脱敏评测集与可复现指标(A21):python main.py benchmark(别名 bench)在虚构群聊上跑真实链路,输出召回 / 误报 / 待办 / 截止 / 去重 / 延迟 / 成本 / 置信度分布,离线、确定性,可当 CI 回归门槛。

第一版评测基线(500 条 / seed=20261008):召回 100%、误报 0.5%、待办与截止时间 100%、跨群去重 100%、延迟中位 0.0 / P95 31.6 分钟。详见 docs/BENCHMARK.md。

尚未完成(随后续小版本)

  • A8 低置信度人工确认:移动端已有候选确认 / 完成 / 忽略 / 纠错,但「低置信度自动进待确认 + 反馈回收」这条闭环还没做完。
  • A9 群级个性化策略:目前只有全局白名单 / 安静群 / 单通道,尚未做到每群独立配静默、关键词、等级、模型档与渠道。

兼容性

  • 无破坏性变更。 data/ 数据库增量迁移(新增 llm_calls 表;老库自动补 route / route_reason 列)。
  • 不配 QQ_DIGEST_LLM_MODEL_LIGHT 时分级路由不启用,行为与 v0.2.0 完全一致。
  • 费用单价默认 0(不折算),需按自身实际价目设置。

测试

403 个用例通过(新增 providers / llmstats / confidence / benchmark / routing 五个测试文件)。

完整改动:v0.2.0...v0.3.0

v0.2.0 — 可解释 + 可贡献(Phase 0)

Choose a tag to compare

@wc985732-lang wc985732-lang released this 08 Oct 15:59

v0.2.0 — 可解释 + 可贡献(Phase 0)

这个版本不堆「更 AI」的功能,而是把系统变得可解释、可测试、易安装、易贡献。

亮点

  • 决策日志:每条消息「为什么被推 / 没被推」结构化落库,python main.py decisions 可查;
    夜间静默、额度用尽、大模型失败挡住的消息记为「延后未决」,拿到最终结论即自动更新。
  • 测试数据模拟器:python main.py simulate 用虚构群聊回放生产同一条链路,离线、确定性(--seed)、
    可导出 JSONL fixture。实测:500 条消息 → 过滤 377 + 去重 54 → 68 条要点 → 23 次通知 → 63 项待办。
  • 26 秒脱敏演示:片子由代码渲染而非录屏,画面里的数字全部取自那次真实回放;输入全为虚构数据并逐帧带水印,可公开发布。

演示

  • 全链路诊断:python main.py doctor 一键检查 NapCat / OneBot / 群白名单 / 推送 / LLM / 访问层。
  • 安全边界:数据流向与加固清单、依赖供应链核查、27 个安全回归用例并入 CI;
    并处置了第三方安全审计(唯一真实缺陷是「缺 qq-botpy 时整个进程退出」,现已降级为单通道不可用)。
  • 可贡献:CONTRIBUTING、Issue/PR 模板、FAQ、故障演练手册(docs/DR-DRILL.md)、ROADMAP v1。

兼容性

  • 无破坏性变更。 data/ 数据库增量迁移(新增 decisions 表),旧库可直接用。
  • 未安装 qq-botpy 时,仅「QQ 官方机器人」通道不可用,其余功能与整套测试照常运行。

测试

268 个用例通过;屏蔽 qq-botpy 时同样 268 通过(1 skip)。

完整改动:v0.1.0...v0.2.0

v0.1.0

Choose a tag to compare

@wc985732-lang wc985732-lang released this 06 Oct 15:13

首个公开版本:把 QQ 群里真正要紧的通知过滤、提炼后推到微信,并汇总成手机待办台。

功能

  • NapCat / OneBot v11 只读接入,只处理 QQ_DIGEST_GROUPS 白名单内的群(留空 = 不处理任何群)
  • 本地规则 + 可选大模型双层筛选:过滤闲聊,提取通知 / 待办 / 截止时间
  • 推送通道:WxPusher / Server酱 / PushPlus / Webhook,失败自动回退
  • 手机待办台 PWA:待确认卡片、完成 / 忽略 / 稍后提醒、截止提醒、每周复盘
  • 群文件与截图解析:PDF / Word / Excel / PPT / zip,扫描版 PDF 走 OCR
  • 跨群重复通知去重、失败重试与降级、夜间静默与推送预算

安全

  • 附件下载仅允许 http(s),解析 DNS 后拒绝本机 / 内网 / 云元数据地址,重定向逐跳复检(SSRF 加固)
  • 群白名单 fail-closed:未配置时不接收任何群
  • 仓库与全部 Git 历史不含任何凭证,pip-audit 0 漏洞

环境

  • Windows 10/11、Python 3.12+、NapCat(或兼容 OneBot v11 的实现)
  • 至少一个推送通道;MIT License

验证

  • 158 项单元测试通过;GitHub Actions(Windows + Python 3.12)绿色