leonathan369-droid/qq-bridge

qq-bridge

QQ Bridge for macOS —— DeepSeek Harness QQ 集成:DSH 设置页控制中心(真实健康检查 / 一键启停 / 运行模式 / QQ 专用模型与推理强度)+ LLBot 适配。上游 Derpyu520/qq-bridge 的衍生版(MIT)。

待分类deepseek-harnessdshllbot

QQ ↔ DeepSeek Harness 桥接

English: README.en.md | 中文: README.md

🍴 本仓库是 Derpyu520/qq-bridge(MIT)的衍生版本,
由 leonathan369-droid 维护:面向 macOS + LLBot 做本机适配,
并新增 DSH 设置页「QQ 桥接」控制中心(真实健康检查 / 一键启停 / 运行模式 / QQ 专用模型与推理强度)。
上游的 OneBot 桥接业务逻辑保持不变;衍生改动与验证记录见 docs/RELEASE-v0.3.0.md。
🗂️ 文档索引(全部文档一句话说明 + 是否仍然有效)见 docs/README.md;仓库目录/脚本命名约定见 docs/FOLDER_MAP.md。
🔒 QQ 会话的权限边界与安全承诺见 RULES.md;第三方组件与数据出机清单见 NOTICE.md。
🎤 独立的「发语音」工具已拆到仓库上一级的 `../voice-tool/`(命令行 voice-cli.mjs / 图形界面 voice-gui.mjs),不再依赖 qq-bridge 运行。

把 QQ 消息接入 DSH agent:QQ 好友/群发来的消息会变成 DSH 会话里的用户消息,agent 的回复(含提问、工具审批)会发回 QQ。

⚠️ 当前版本 `v0.3.3`,适配 DSH 0.2.0-rc.2(在该版本上逐项实测:npm run verify:adaptation)。
鉴权用 ~/.dsh 里持久化的浏览器会话签名密钥离线铸造 Cookie —— DSH 0.1.7 起进程启动 token
只存在于内存、不再落盘,旧版「从 guard 日志里读 token」的方式已失效。agent preset 是 DSH 0.1.7 起的
@deepseek-ai/dsh-agent-preset Cordis 行(~/.dsh/.agent-presets/ 目录机制已废)。协议代次
(Cookie 鉴权 / 斜杠 RPC / /api/remote.mux 事件流)自 DSH 0.1.2-alpha.1 起引入,与更早的点号
endpoint 协议不兼容 —— DSH `0.1.1-rc.2` 及更早请改用 tag
v0.1.0;DSH 0.1.5-rc.1 用
v0.1.5;DSH 0.1.7-rc.2 用
v0.1.7。
v0.2.0 修的主要是会话待处理队列读不出来:桥接退役/重置 QQ 会话时要先清掉 DSH 侧没跑的队列,
而那段解析认的是一个从来不存在的字段(session/control baseline 的 value.queues[])——
于是每一次退役都抛 invalid session/control baseline,队列清不掉、旧任务继续在 DSH 里跑,
而日志里只有一行警告。注意:这不是 0.2.0 引入的——该代码随 v0.1.7 发布,报错日志早于
0.2.0-rc.2 的发布,0.2.0 只是把它翻了出来。现在读队列以一元 RPC session/projections 为主路径、
以 projections[].values.inbox 为回退形状,并补了两条回归网。
同一轮还按 0.2.0 的真实工具清单重新对账了 QQ 安全守卫(新增 15 个必须隐藏的工具名,
含全局层默认启用的 read_mcp_resource、plugin_manager、subagent_codex 等)。
v0.3.0(2026-10-21):DSH 设置页「QQ 桥接」升级为控制中心 —— 四项真实健康检查
(桥接/LLBot/QQ 登录/DSH 连接)、一键启动(幂等、等待扫码不算失败)、进程归属三重校验、
运行模式、QQ 专用模型与推理强度(读 DSH 真实模型目录,默认会话作用域:不写 DSH
全局默认模型)、一次性票据打开控制台、可折叠诊断。回归 32/32;作用域验收脚本
npm run verify:panel-isolation。详见 docs/guides/QQ_PANEL.md
与 docs/RELEASE-v0.3.0.md。
v0.3.3(2026-10-24):修「他看不到图」。本机在跑 Clash/Surge 一类 TUN fake-IP 代理时
(实测 multimedia.nt.qq.com.cn→198.18.0.9、baidu→198.18.0.17),safe-fetch 的 SSRF 防护把
198.18.0.0/15 当内网,于是图片/表情/web_fetch 全部被拦:日志刷「域名解析到内网/本机地址,
已阻止」,QQ 上表现为"消息看得到、图永远看不到"。现在启动时自动识别 fake-IP 环境并只放行该保留段,
且仅对域名生效(URL 里直接写 198.18.x.x、以及 10/127/172.16/192.168/169.254/CGNAT 与 IPv6 内网
一律照旧拦截);/api/status.network.proxyFakeIp 可见结论。同时修掉两处遗留:① qq_get_prompt 在
role.injectPerMessage=false 时 role.hint 恒为空(唤醒提示让 AI 去查,查不到)→ 现在返回角色卡全文
(实测 0 → 4994 字);② 新增 角色卡 → preset 常驻人格同步(npm run check:role / sync:role
+ preset 内 `` 标记,生成 patch 时剥离标记,产物逐字节不变),
解决"控制台改了角色卡、QQ 里的 AI 一点没变"。回归 37/37。详见
docs/RELEASE-v0.3.3.md。
v0.3.2(2026-10-24):修第二个「发消息没反应」的形态 —— 回合外事件把会话永久判成繁忙。
DSH 在 turn/end 之后还会往同一会话追加回合外事件(实测 subagent/catalog:mnemon 插件的
空闲检查子 agent)。桥接旧代码给每条 session/event 都建回合收集器,而收集器只在收到
turn/end 时删除 → 这个收集器永远等不到结束,isConversationBusyV2() 恒为 true,
之后每一次唤醒(@/拍一拍/关键词/提问)都只写进 pendingWakeReasons「暂存」,一条不投递:
QQ 上完全静默,而 DSH 侧会话空闲、消息也正常流入(本次群未读堆到 13)。现在:① 只有
回合内事件才建收集器(src/turn-tracker.js,未知类型默认不建);② 60 秒兜底回收
无回合起点的残留收集器与超过 30 分钟仍未结束的回合;③ DSH 重连恢复进行中回合时补记回合
起点。回归 35/35。详见 docs/RELEASE-v0.3.2.md。
v0.3.1(2026-10-24):修一个「面板全绿、消息一条进不来」的隐蔽故障。先启动服务、
再扫码登录 LLBot 时,桥接的 OneBot WebSocket 首次连接会失败,而失败路径上 Node 22 内置
WebSocket 只发 `error` 不发 `close`,@snowluma/sdk 的 connectPromise 于是永不 settle、
之后每次 connect() 都返回同一个 pending promise → 永久不再重连(close 型的 token
自愈也一并不跑)。用户侧表现:QQ 明明已登录,发消息却完全没反应;旧面板只看端口/HTTP,
四项全绿报「全部就绪」。现在:① 桥接常驻 WS 连接看门狗(卡在连接中超过 8s 就强制
重建,连续失败顺带自愈 token);② 面板把「桥接 ↔ LLBot」单列为消息链路,断了显示
「收发链路中断」并给一键「重启桥接」,不再冒充就绪;③ 连接错误日志不再打成 {}。
回归 34/34(新增 WS 看门狗单测 + 真实进程端到端恢复测试)。详见
docs/RELEASE-v0.3.1.md。
逐条改动说明见 docs/guides/DSH_020_ADAPTATION.md。
本次更新的完整说明见 Release v0.2.0。
默认分支 main 就是本版本,git clone 直接拿到,无需切换分支。
QQ 消息 ──► SnowLuma(OneBot v11 WS)──► 本桥接进程 ──► DSH Web API (127.0.0.1:3080/api)
                                                ▲                      │
                                                └── agent 回复/提问/审批 ┘

项目展示

界面预览

装进 DeepSeek Harness 后,设置 → QQ 桥接 是完整的本地控制中心:四项真实健康检查、一键启动、服务归属、运行模式、QQ 专用模型与推理强度、诊断,全在一页。

QQ 专用模型 / 推理强度:模型目录、Provider 分组、搜索、推理档位全部来自 DSH 的真实能力;只作用于 QQ 会话,不改 DSH 全局默认模型。

截图中路径 / QQ 号为示例值(已脱敏);运行时显示你自己的配置。

介绍视频

📽️ AI 仿真群友 - 项目介绍视频(约 11 MB)

视频改由 Release 附件托管,不在仓库里——只想安装桥接的人不必再下载这 11 MB(它此前占整个仓库体积的 88%)。

架构

  • QQ 侧:@snowluma/sdk 的 SnowLumaWebSocketClient(OneBot v11 WebSocket 客户端,自动重连)
  • DSH 侧:适配 DSH 0.1.2 起引入、0.2.0-rc.2 上逐项复核的协议——用本机持久化签名密钥铸造会话 Cookie 鉴权、/api// 斜杠 RPC、/api/remote.mux + session/follow 事件流(session/control 的队列读 value.projections[].values.inbox,另有一元 session/projections 主路径);复用 AbstractApiClient 传输层但不再依赖旧版 zod value schema。QQ 会话的模型由桥接按 config.json 的 dsh.provider/model/reasoningEffort 通过面板 host 半的会话局部应用固定(sessionController.agents.selectForNextRequest,等价官方 session/selectModel 去掉写全局默认那一步;默认 deepseek-flash = DeepSeek-V41-Flash,多模态)。面板里切换模型即改这一处;dsh.modelScope=global 才会回到会写 DSH 全局默认的旧行为
  • agent 自主收发 QQ:DSH 的 MCP 客户端(~/.dsh/profiles/web/cordis.patch.yml 配置)接入三个 MCP server:
  • snowluma(桥接自带 src/mcp-snowluma-safe.js):QQ 动作安全子集(查状态/查群/查消息/发消息,发送强制白名单;发送工具支持可选 replyToMessageId 引用回复)
  • snowluma-host(桥接自带 src/mcp-host-server.js):只有 snowluma_status(只读探活 get_login_info)。

⚠️ v0.1.5 起移除了 `start_snowluma` / `stop_snowluma`(以及 snowluma.allowProcessControl 配置项)—— 原因是 SnowLuma EULA §5.4 规定「将其并入第三方安装包或 Docker 镜像、通过自动化脚本部署」 须事先取得书面授权,而原生组件属专有组件。本程序只探测、不部署:SnowLuma 的安装、启动与扫码 始终由你自己完成(详见 LICENSE、NOTICE.md 与 RULES.md)。

  • web-search-safe(桥接自带 src/mcp-web-search-safe.js):只读 web_search / web_fetch(带 SSRF 防护),供 agent 查网络用语/资料。

⚠️ 它会把搜索关键词发给 Bing、并按模型决定抓取公网 URL;黑话学习默认开启,会拿群聊里提取的词条去搜。 数据出机清单见 NOTICE.md 的「数据出机清单」,不需要就关掉黑话自动研究(slang.autoResearch)。