Observed since 20 Oct, 22:38 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
Mirror a live pi coding-agent session to a QQ private chat (official QQ Bot API).
English | 简体中文
把正在运行的 pi 会话镜像到一个 QQ 私聊:终端与 QQ 双向同步。
Mirror a live pi coding-agent session to a QQ private chat, using the official QQ Bot API. Terminal and QQ stay in sync; reasoning (
thinking) and tool calls never leak to QQ.
传输层使用腾讯官方 SDK @tencent-connect/qqbot-nodejs(MIT)。本扩展只是一层薄胶水,不依赖任何第三方插件。
thinking 永不外发。autoConnect: false,不随手抢占机器人。AppID 与 AppSecret。用 pi 的包管理安装(推荐):
pi install git:github.com/0x5c0f/pi-qqbot
固定版本:
pi install git:github.com/0x5c0f/pi-qqbot@v0.1.0
若已发布到 npm:
pi install npm:@0x5c0f/pi-qqbot
项目内安装(.pi/)加 -l:
pi install -l git:github.com/0x5c0f/pi-qqbot
安装后请完全退出并重启 pi(扩展在启动时加载)。
/qq-setup
填写 AppID、AppSecret、是否有 Markdown 权限 → 保存并连接(不含绑定)。/qq-bind 进入绑定模式。之后终端与 QQ 双向同步即可。只有白名单里的 openid 能驱动会话。
| 命令 | 作用 |
|---|---|
/qq-setup | 交互式配置:填 AppID/AppSecret 并保存、连接(不含绑定) |
/qq-bind | 进入绑定模式:把下一条 QQ 私聊的 openid 写入白名单(换 QQ 号 / 白名单丢失时用) |
/qq-connect | 连接 QQ 网关(抢单实例锁) |
/qq-disconnect | 断开 QQ 网关并释放锁 |
/qq-status | 查看连接、autoConnect、锁持有者、目标会话、被动回复余量、日志路径、最近错误 |
切换终端:在旧实例 /qq-disconnect,再到新实例 /qq-connect。
配置文件由 /qq-setup 生成,默认路径 ~/.pi/agent/pi-qqbot.json(权限 0600):
{
"appId": "YOUR_QQBOT_APP_ID",
"appSecret": "YOUR_QQBOT_APP_SECRET",
"markdownSupport": false,
"allowFrom": [],
"debounceMs": 1200,
"maxChunkChars": 4500,
"forwardTerminal": true,
"showToolTrace": false,
"allowGroup": false,
"autoConnect": false,
"streamIntermediate": false
}
| 字段 | 默认 | 说明 |
|---|---|---|
appId / appSecret | 必填 | QQ 开放平台机器人凭据 |
markdownSupport | false | 机器人是否已通过 QQ Markdown 权限审核;未审核务必保持 false |
allowFrom | [] | 允许驱动本会话的 QQ openid 白名单;空 = 只能绑定,不能使用 |
debounceMs | 1200 | 助手输出的合并窗口(毫秒),窗口内多条消息合并为一次 QQ 发送 |
maxChunkChars | 4500 | 单条 QQ 文本上限(平台约 5000,留余量) |
forwardTerminal | true | 把终端输入镜像到 QQ |
showToolTrace | false | 是否在下一条消息前附上工具名 |
allowGroup | false | 是否接受群聊 @(默认关闭) |
autoConnect | false | 是否在 pi 启动时自动连接。false = 需手动 /qq-connect |
streamIntermediate | false | 是否把助手的中间消息实时逐条发出。默认 false = 每个回合合并成一条 |
环境变量覆盖:PI_QQBOT_CONFIG、PI_QQBOT_LOG、PI_QQBOT_STATE、PI_QQBOT_LOCK。
同步是三个方向:
① QQ → pi 注入当前会话(消息带 [QQ] 标记,用于防止回声)
② pi → QQ assistant 的 text 块回传
③ 终端 → QQ 终端输入镜像(前缀 🖥 终端)
text 块,thinking / toolCall 天然被排除。showToolTrace 默认关闭;工具执行期间仅用 QQ「输入中」提示(不发消息)。agent_settled)再合并发送(超长按上限分片)。这样通常只消耗 1~2 次被动回复,不会把配额浪费在过程碎语上、也不会因配额耗尽而丢失最终答案。想要实时逐条,设 streamIntermediate: true。~/.pi/agent/pi-qqbot.lock;另一存活的 pi 持有时会拒绝连接并提示 PID;持锁进程崩溃后锁自动回收。scope / targetId / msgId),不保存任何聊天内容。因此换一个 pi 会话连接 QQ 时,QQ 的历史记录不会注入新会话,上下文保持干净。想延续上下文请用 pi 自己的 /resume。~/.pi/agent/logs/pi-qqbot.log(权限 0600;超过 2MB 自动截断)。路径可用 /qq-status 查看。
allowFrom 为空)时,收到的 QQ 消息会被忽略。0600,且不会提交到 git。git clone https://github.com/0x5c0f/pi-qqbot
cd pi-qqbot
npm install
npm test
测试完全离线,不需要真实 QQ 凭据:
test/core.test.ts、test/state.test.ts、test/lock.test.ts — 单元测试:文本抽取(排除 thinking)、分片、被动预算、去抖、注入标记、状态持久化、单实例锁。test/load-harness.mjs — 用 jiti 加载扩展,校验事件/命令注册与占位配置安全失败。test/flow-harness.mjs — 假 QQ 传输跑端到端场景(白名单、去重、回声防护、thinking 过滤、去抖、终端镜像、预算降级与预警)。test/bind-harness.mjs — 绑定流程与目标持久化。test/setup-harness.mjs — /qq-setup 与 /qq-bind 的职责分离。单元测试使用 Node 原生 TypeScript 运行,需要 Node >= 22.18;harness 通过 devDependency
jiti加载扩展。
index.ts pi 扩展入口:生命周期 / 事件 / 命令
core.ts 纯逻辑:文本抽取、分片、被动预算、去抖、注入标记
config.ts 配置加载、校验、保存(0600)
state.ts 回复目标持久化(跨会话)
lock.ts 单实例锁
log.ts 文件日志
pi-qqbot.example.json 配置示例
test/ 单元测试 + 离线 harness
allowGroup 默认关闭。streamIntermediate: true 可恢复逐条实时;官方 stream_messages 仅 C2C,可作为后续增强)。Download counts and popularity will appear here as the collector receives them.
This describes our collected data; it is not a security assessment.
Observed since 20 Oct, 22:38 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
package:cb1a4730bc2f6486ade9dca8b9f45e5ff0391abdc22b6addacf093ba99cb3652