npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

pi-qq-integration

v0.5.3

Published

QQ integration for pi — control pi from QQ | pi QQ 集成 — 在 QQ 中操控 pi

Readme

English

pi-qq-integration — 中文版

QQ 中操控 pi。安装此扩展后,pi 启动时会自动加载扩展并默认自动连接 QQ Bot(可在配置中关闭)。连接后即可通过 QQ 向 pi 发消息、查看 session 列表、浏览历史对话;也可随时用 /qq-connect/qq-disconnect 手动控制连接。


安装

pi install npm:pi-qq-integration

快速开始

1. 注册 QQ Bot

QQ 开放平台 创建一个机器人应用,获取 AppIDAppSecret

2. 创建配置文件

创建 ~/.pi/agent/qq-integration-config.json

{
  "appId": "你的 AppID",
  "appSecret": "你的 AppSecret"
}

3. 启动 pi

pi

扩展加载后,pi 会话启动时会自动连接 QQ Bot(默认行为)。如需关闭自动连接,在配置文件加 "autoConnect": false 后重启 pi,再用 /qq-connect 手动连接;断开用 /qq-disconnect

现在在 QQ 中给机器人发消息,就能和 pi 对话了。


配置项(qq-integration-config.json)

配置文件路径:~/.pi/agent/qq-integration-config.json(位于 pi 的 agent 数据目录,与扩展代码目录无关)。

顶层字段

| 字段 | 类型 | 必填 | 默认值 | 说明 | |------|------|------|--------|------| | appId | string | ✅ | — | QQ 开放平台机器人应用的 AppID | | appSecret | string | ✅ | — | QQ 开放平台机器人应用的 AppSecret(敏感,勿提交 git) | | instanceId | string | ❌ | PID | 多实例下本实例的唯一 ID(默认取进程 PID,用于 #to <PID> 切换与消息署名) | | role | "auto" \| "leader" \| "follower" | ❌ | "auto" | 多实例角色:auto 由文件锁自动选举;leader 强制持有 QQ 连接;follower 强制经 IPC 接入 leader | | autoConnect | boolean | ❌ | true | pi 启动时是否自动连接 QQ Bot;设为 false 则需手动 /qq-connect | | allowedUsers | string[] | ❌ | — | 允许向 pi 发 prompt 的 c2c 用户 openid 白名单。未配置则放行所有私聊消息(会输出安全告警)。强烈建议配置,以防远程提示词注入 | | allowedGroups | string[] | ❌ | — | 允许向 pi 发 prompt 的群 openid 白名单。未配置则放行所有 @机器人消息 |

settings 字段(转发设置)

| 字段 | 类型 | 默认值 | 说明 | |------|------|--------|------| | forwardDesktopMessages | boolean | false | 桌面端(pi 终端)输入的消息是否转发到 QQ | | forwardToolCalls | boolean | false | 工具调用及其结果是否转发到 QQ(与 lastMessageOnly 互斥;开启一个会自动关闭另一个,配置文件与 #settings 均强制) | | lastMessageOnly | boolean | false | 只转发整次 agent 运行的最后一条 assistant 回复(与 forwardToolCalls 互斥;开启一个会自动关闭另一个) | | defaultSession | object | undefined | undefined | 默认 QQ 转发目标。收到 QQ 消息时会自动更新为该消息来源会话;也可由 /qq-target 或 QQ #target 设置 |

settings 内的字段既可在配置文件里静态写死,也可在 QQ 内用 #settings 命令动态调整并持久化。#settings 命令对前两个开关使用了简写别名:forwardMessages 对应 forwardDesktopMessagesforwardTools 对应 forwardToolCalls

完整示例

{
  "appId": "你的 AppID",
  "appSecret": "你的 AppSecret",
  "autoConnect": true,
  "role": "auto",
  "settings": {
    "forwardDesktopMessages": false,
    "forwardToolCalls": false,
    "lastMessageOnly": false
  }
}

环境变量

| 变量 | 说明 | |------|------| | QQ_INTEGRATION_DATA_DIR | 覆盖数据目录(默认 ~/.pi/agent) | | QQ_API_BASE | 覆盖 QQ API 域名(默认 https://api.sgroup.qq.com) | | QQ_TOKEN_API | 覆盖 Token API 地址(默认 https://bots.qq.com/app/getAppAccessToken) |

多实例

同时运行多个 pi 实例时,用文件锁选举唯一的 leader 持有 QQ 连接;其余实例作为 follower 经本地 IPC 把 QQ 收发委托给 leader(macOS/Linux 用 Unix socket,Windows 用命名管道)。

  • role: "auto"(默认):谁先抢到锁谁是 leader,其余自动成为 follower。
  • role: "leader" / "follower":强制角色。follower 即使 leader 宕机也不会尝试接管成为 leader。
  • instanceId:默认即进程 PID,同时作为实例署名与 #to <PID> 定向路由的标识;仅在需要固定 ID 时手动设置。

消息署名 — 所有发往 QQ 的消息都会带一段引用块署名,标明消息来自哪个实例:

> 【session名-3863】

<消息内容>

(session 名为当前 pi session 名;未命名时署名为 > 【PID】。)该署名同时是引用消息路由的兜底依据(见下)。

引用消息定向路由 — 在 QQ 中引用(回复)某条消息时,消息会自动路由回发送被引用消息的那个实例(基于 ref_idx 映射,60 分钟 TTL;未命中时按被引用内容中的署名唯一匹配兜底)。也就是说,想给某个特定实例发消息,直接引用它之前发的消息回复即可


架构

QQ 用户
  │
  ├─ 发消息 → QQ Bot 服务器 → WebSocket
  │                                │
  │                     ┌──────────▼──────────┐
  │                     │  pi-qq-integration  │
  │                     │  ws-client.ts       │
  │                     │    ↕ WebSocket      │
  │                     │  command-handler.ts │
  │                     │    ↕ #cmd 解析      │
  │                     │  index.ts           │
  │                     │    ↕ sendUserMessage│
  │                     └──────────┬──────────┘
  │                                │
  │                     ┌──────────▼──────────┐
  │                     │      pi 引擎         │
  │                     │   处理 prompt 并回复   │
  │                     └──────────┬──────────┘
  │                                │
  └─────── REST API ←──── 回复内容

两个独立通道:

  • WebSocket — 接收 QQ 消息(长连接,带心跳和断线重连)
  • REST API — 发送回复到 QQ,按会话类型 POST 到对应端点:/v2/users/{openid}/messages(c2c)、/v2/groups/{group_openid}/messages(群)、/channels/{channel_id}/messages(频道)

pi Slash 命令

| 命令 | 说明 | |------|------| | /qq-connect | 手动连接 QQ Bot | | /qq-disconnect | 断开 QQ Bot 连接 | | /qq-status | 查看连接状态概览(角色、锁、WebSocket、Token) | | /qq-diagnose | 查看详细诊断信息 | | /qq-logs | 查看最近 30 条日志 | | /qq-logs-path | 查看日志文件路径 | | /qq-logs-clear | 清空日志文件 | | /qq-target | 设置/查看默认 QQ 转发目标 |


QQ 命令

在 QQ 中给机器人发送的消息,如果不以 # 开头,会直接作为 prompt 发给 pi。

| 命令 | 说明 | |------|------| | #help | 显示帮助 | | #sessions [页码] | 跨项目列出全部 session,每页 10 条,最近使用在前 | | #history [N] | 查看当前实例 session 的最近 N 条消息(默认 5) | | #target | 将当前 QQ 会话设为默认转发目标 | | #settings | 查看/修改转发设置(#setting 为别名) | | #instances | 列出在线实例(ID、角色、认领会话的名字/最近消息摘要) | | #to <PID/名称> [内容] | 查看当前绑定实例 / 切换会话到指定实例 / 向指定实例定向发送内容 | | #create <序号/名称> | 创建新实例并复用指定 session | | #create new [--dir <目录>] | 创建全新 session 的新实例(可指定工作目录)| | #close <PID> [PID...] | 关闭实例(支持空格分隔多个 PID) |

桌面端消息转发

开启桌面端转发(#settings forwardMessages on)后,桌面端输入的消息会同步转发到 QQ。目标按优先级选择:

  1. 最近一条 QQ 消息来源的会话(收到 QQ 消息时会自动更新 defaultSession
  2. 手动设置的默认目标(/qq-target 或 QQ #target)——仅在尚未收到任何 QQ 消息时生效

注: 从 QQ 转发进 pi 的消息会带来源标签前缀(私聊 [QQ]、群聊 [QQ群])。该前缀也用于识别并跳过桌面端回响,避免转发回环。

/qq-target c2c <用户openid> [备注]        # 私聊(备注可选)
/qq-target group <群openid> [备注]         # 群聊
/qq-target channel <频道id> [备注]         # 频道
/qq-target                                 # 查看当前目标(别名:show)
/qq-target clear                           # 清除

#settings 示例

你: #settings
Bot: ## ⚙️ QQ Bot 设置
     | 选项 | 状态 | 说明 |
     | forwardMessages | ❌ 关 | 桌面端消息转发到 QQ |
     | forwardTools | ✅ 开 | 工具调用转发到 QQ |
     | lastMessageOnly | ❌ 关 | 只转发整次回复的最后一条 assistant 回复 |

你: #settings forwardTools on
Bot: ✅ **工具调用转发** 已开启,同时 `lastMessageOnly` 已自动关闭。

你: #settings lastMessageOnly on
Bot: ✅ **只转发最后一条回复** 已开启,assistant 整次运行仅发送一条最终回复;`forwardTools` 已自动关闭。

文件结构

pi-qq-integration/
├── index.ts              # 入口:初始化、事件、slash 命令
├── constants.ts          # 集中常量(路径、URL、超时值)
├── config.ts             # 配置文件读写(原子写入)
├── auth.ts               # Token 管理 + 自动刷新
├── lock.ts               # 文件锁(O_EXCL 原子创建)
├── ws-client.ts          # WebSocket 客户端
├── api-client.ts         # REST API 客户端
├── ipc.ts                # IPC(leader-follower 委派;Unix socket / Windows 命名管道)
├── registry.ts           # 实例注册表(原子写入)
├── routing.ts            # 引用消息路由纯函数(ref_idx + 署名兜底)
├── validation.ts         # session/sessionKey 校验、参考名清洗
├── session-manager.ts    # Session 浏览
├── command-handler.ts    # #命令解析
├── logger.ts             # 文件日志(自动截断)
├── types.ts              # 类型定义
└── package.json

多实例细节

~/.pi/agent/
├── qq-integration.lock          # 文件锁(O_EXCL 原子创建)
│   └─ JSON: { pid, startedAt, heartbeatAt } (心跳每 30 秒更新)
└── qq-integration/
    ├── registry.json             # 实例注册表(原子写入)
    └── instances/
        └── <pid>.sock            # IPC Unix socket(leader;Windows 为命名管道)
  • 第一个实例获取锁 → 成为 leader → 连接 QQ Bot
  • 后续实例检测到锁 → 成为 follower → 通过 IPC 连接 leader
  • leader 崩溃或退出后 PID 失效 → follower 在重连循环中自动接管锁升级为 leader(故障转移);role: follower 强制跟随时不升级
  • leader 宕机期间 follower 静默重试(仅写日志,不刷 UI 提示),连接恢复时才通知

日志

所有调试日志写入 ~/.pi/agent/qq-integration.log。使用 /qq-logs 查看最近 30 条,/qq-logs-path 查看路径。日志文件达到 5 MB 自动截断。


注意事项

  1. Token 安全 — Token 有效期约 2 小时,自动刷新。连续 3 次刷新失败后自动断开并通知。
  2. 消息频率 — 主动消息每月每用户/群限 4 条(QQ 官方平台限制),被动回复较宽松。
  3. Session 管理 — 用 #create 创建新实例(复用 session 或全新开始),#sessions 列出全部 session,#close 关闭实例。实例内不再支持会话切换(用 #create + #to 替代)。
  4. 设置持久化#settings 变更保存到配置文件,/reload 不丢失。
  5. 群聊消息 — 仅接收 @机器人的消息。
  6. 配置文件 — 含 AppSecret,勿提交 git。

开发

cd ~/.pi/agent/extensions/pi-qq-integration
npm install          # 安装依赖
npm run build        # 编译 TypeScript
npm run typecheck    # 仅类型检查
npm test             # 运行测试套件(node:test,无额外开发依赖)
# 编辑代码后在 pi 中 /reload 热重载

依赖 — 唯一的运行时第三方依赖是 ws(WebSocket 客户端,用于 ws-client.ts),其余全部使用 Node.js 内置模块。


贡献者

感谢 @illusionlie 报告 Windows IPC bug (#1) 并提交修复 PR (#2)。