From 955fdda9c96fc2231d6aa6e66703394612da5ff9 Mon Sep 17 00:00:00 2001 From: Stephen An Date: Sun, 8 Mar 2026 23:47:32 +0800 Subject: [PATCH 1/4] Add Windows upgrade script as alternative to upgrade.sh --- scripts/upgrade.bat | 66 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 scripts/upgrade.bat diff --git a/scripts/upgrade.bat b/scripts/upgrade.bat new file mode 100644 index 0000000..22401b4 --- /dev/null +++ b/scripts/upgrade.bat @@ -0,0 +1,66 @@ +@echo off +setlocal enabledelayedexpansion + +echo === QQBot Upgrade Script === + +set "foundInstallation=" + +set "clawdbotDir=%USERPROFILE%\.clawdbot" +if exist "%clawdbotDir%\" ( + call :CleanupInstallation clawdbot + set "foundInstallation=clawdbot" +) + +set "openclawDir=%USERPROFILE%\.openclaw" +if exist "%openclawDir%\" ( + call :CleanupInstallation openclaw + set "foundInstallation=openclaw" +) + +if "%foundInstallation%"=="" ( + echo clawdbot or openclaw not found + exit /b 1 +) + +set "cmd=%foundInstallation%" + +echo. +echo === Cleanup Complete === +echo. +echo Run these commands to reinstall: +for %%I in ("%~dp0..") do set "qqbotDir=%%~fI" +echo cd %qqbotDir% +echo %cmd% plugins install . +echo %cmd% channels add --channel qqbot --token "AppID:AppSecret" +echo %cmd% gateway restart +exit /b 0 + +:CleanupInstallation +set "AppName=%~1" +set "appDir=%USERPROFILE%\.%AppName%" +set "configFile=%appDir%\%AppName%.json" +set "extensionDir=%appDir%\extensions\qqbot" + +echo. +echo ^>^>^> Processing %AppName% installation... + +if exist "%extensionDir%\" ( + echo Deleting old plugin: %extensionDir% + rd /s /q "%extensionDir%" 2>nul || ( + echo Warning: Could not delete %extensionDir% ^(permission denied^) + echo Please delete it manually if needed + ) +) else ( + echo Old plugin directory not found, skipping +) + +if exist "%configFile%" ( + echo Cleaning qqbot fields from config... + set "configPath=%configFile:\=/%" + node -e "const fs=require('fs');const c=JSON.parse(fs.readFileSync('!configPath!','utf8'));if(c.channels&&c.channels.qqbot){delete c.channels.qqbot;console.log(' - deleted channels.qqbot');}if(c.plugins&&c.plugins.entries&&c.plugins.entries.qqbot){delete c.plugins.entries.qqbot;console.log(' - deleted plugins.entries.qqbot');}if(c.plugins&&c.plugins.installs&&c.plugins.installs.qqbot){delete c.plugins.installs.qqbot;console.log(' - deleted plugins.installs.qqbot');}if(c.plugins&&c.plugins.allow&&Array.isArray(c.plugins.allow)){const i=c.plugins.allow.indexOf('qqbot');if(i^!==-1){c.plugins.allow.splice(i,1);console.log(' - deleted qqbot from plugins.allow array');}}fs.writeFileSync('!configPath!',JSON.stringify(c,null,2));console.log('Config file updated');" || ( + echo Warning: Node.js error + ) +) else ( + echo Config file not found: %configFile% +) +exit /b 0 From 1359bbed67bad67e8bcbb0407529eec893a734c3 Mon Sep 17 00:00:00 2001 From: Jerry Chen <1261449269@qq.com> Date: Mon, 9 Mar 2026 05:02:50 +0000 Subject: [PATCH 2/4] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E7=B4=A7?= =?UTF-8?q?=E6=80=A5=E5=91=BD=E4=BB=A4=E7=AB=8B=E5=8D=B3=E6=89=A7=E8=A1=8C?= =?UTF-8?q?=E5=8A=9F=E8=83=BD/stop?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/gateway.ts | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/src/gateway.ts b/src/gateway.ts index 1a87bdd..00fd2fb 100644 --- a/src/gateway.ts +++ b/src/gateway.ts @@ -405,6 +405,10 @@ export async function startGateway(ctx: GatewayContext): Promise { // ============ 按用户并发的消息队列(同用户串行,跨用户并行) ============ // 每个用户有独立队列,同一用户的消息串行处理(保持时序), // 不同用户的消息并行处理(互不阻塞)。 + + // 紧急命令列表:这些命令会立即执行,不进入队列 + const URGENT_COMMANDS = ["/stop"]; + const userQueues = new Map(); // peerId → 消息队列 const activeUsers = new Set(); // 正在处理中的用户 let messagesProcessed = 0; @@ -420,6 +424,32 @@ export async function startGateway(ctx: GatewayContext): Promise { const enqueueMessage = (msg: QueuedMessage): void => { const peerId = getMessagePeerId(msg); + const content = (msg.content ?? "").trim().toLowerCase(); + + // 检测是否为紧急命令 + const isUrgentCommand = URGENT_COMMANDS.some(cmd => content.startsWith(cmd.toLowerCase())); + + if (isUrgentCommand) { + log?.info(`[qqbot:${account.accountId}] Urgent command detected: ${content.slice(0, 20)}, executing immediately`); + + // 清空该用户队列中所有待处理消息 + const queue = userQueues.get(peerId); + if (queue) { + const droppedCount = queue.length; + queue.length = 0; // 清空队列 + totalEnqueued = Math.max(0, totalEnqueued - droppedCount); + log?.info(`[qqbot:${account.accountId}] Dropped ${droppedCount} queued messages for ${peerId} due to urgent command`); + } + + // 立即异步执行紧急命令,不等待 + if (handleMessageFnRef) { + handleMessageFnRef(msg).catch(err => { + log?.error(`[qqbot:${account.accountId}] Urgent command error: ${err}`); + }); + } + return; + } + let queue = userQueues.get(peerId); if (!queue) { queue = []; From 46c9c27162194b4b1bd6bae668cfd768251623b7 Mon Sep 17 00:00:00 2001 From: sliverp Date: Sat, 14 Mar 2026 18:06:40 +0800 Subject: [PATCH 3/4] =?UTF-8?q?docs(changelog):=20=E6=96=B0=E5=A2=9E=201.6?= =?UTF-8?q?.1=20=E7=89=88=E6=9C=AC=E5=8F=91=E5=B8=83=E8=AF=B4=E6=98=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/changelog/1.6.1.md | 17 +++++++ package.json | 2 +- skills/qqbot-cron/SKILL.md | 92 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 110 insertions(+), 1 deletion(-) create mode 100644 docs/changelog/1.6.1.md diff --git a/docs/changelog/1.6.1.md b/docs/changelog/1.6.1.md new file mode 100644 index 0000000..a062054 --- /dev/null +++ b/docs/changelog/1.6.1.md @@ -0,0 +1,17 @@ +# 1.6.1 + +## 中文 + +### ✨ 新增 + +- **`/stop` 紧急命令支持**(PR #134 by [@jerryliang122](https://github.com/jerryliang122)):用户发送 `/stop` 时,命令会立即执行,不进入消息队列。同时清空该用户所有待处理的排队消息,实现即时中断 AI 对话的能力。 +- **Windows 升级脚本**(PR #130 by [@anyangmvp](https://github.com/anyangmvp)):新增 `scripts/upgrade.bat`,为 Windows 用户提供与 `upgrade.sh` 等价的一键升级脚本,自动清理旧插件目录和配置文件中的 qqbot 字段,并输出重新安装指引。 + +--- + +## English + +### ✨ New + +- **`/stop` urgent command support** (PR #134 by [@jerryliang122](https://github.com/jerryliang122)): When a user sends `/stop`, the command is executed immediately without entering the message queue. All pending queued messages for that user are also cleared, enabling instant interruption of ongoing AI conversations. +- **Windows upgrade script** (PR #130 by [@anyangmvp](https://github.com/anyangmvp)): Added `scripts/upgrade.bat` as a Windows equivalent to `upgrade.sh`. It automatically cleans up the old plugin directory and removes qqbot-related fields from the config file, then prints reinstall instructions. diff --git a/package.json b/package.json index eda973c..d637796 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@sliverp/qqbot", - "version": "1.6.0", + "version": "1.6.1", "type": "module", "main": "dist/index.js", "types": "dist/index.d.ts", diff --git a/skills/qqbot-cron/SKILL.md b/skills/qqbot-cron/SKILL.md index d01a15e..f74a7b3 100644 --- a/skills/qqbot-cron/SKILL.md +++ b/skills/qqbot-cron/SKILL.md @@ -19,6 +19,98 @@ metadata: {"openclaw":{"emoji":"⏰","requires":{"config":["channels.qqbot"]}}} --- +## 🛠️ 两种调用方式 + +### 方式一:cron 工具调用(推荐) + +如果你的环境中有 `cron` 工具,使用 JSON 参数直接调用: + +```javascript +cron({ + "action": "add", + "job": { + "name": "喝水提醒", + "schedule": { "kind": "at", "atMs": 1770734300000 }, + "sessionTarget": "isolated", + "wakeMode": "now", + "deleteAfterRun": true, + "payload": { + "kind": "agentTurn", + "message": "暖心提醒内容", + "deliver": true, + "channel": "qqbot", + "to": "qqbot:c2c:0DEBF031..." + } + } +}) +``` + +### 方式二:exec 工具执行 CLI 命令(备用) + +⚠️ **如果没有 cron 工具,使用 exec 工具调用 openclaw CLI 命令。** + +**重要区别:CLI 参数名和 JSON API 不一样!** + +| JSON API 字段 | CLI 参数 | +|--------------|----------| +| `action: "add"` | `openclaw cron add` | +| `job.schedule.kind: "at"` | `--at "30s"` 或 `--at "2026-03-14T10:00:00Z"` | +| `job.schedule.kind: "cron"` | `--cron "0 8 * * *" --tz "Asia/Shanghai"` | +| `job.schedule.atMs` | `--at "30s"`(相对时间)或 ISO 时间字符串 | +| `job.sessionTarget: "isolated"` | `--session isolated` | +| `job.wakeMode: "now"` | `--wake now` | +| `job.deleteAfterRun: true` | `--delete-after-run` | +| `job.payload.kind: "agentTurn"` | `--message "..."` | +| `job.payload.message` | `--message "..."` | +| `job.payload.deliver: true` | `--announce` | +| `job.payload.channel: "qqbot"` | `--channel qqbot` | +| `job.payload.to` | `--to "qqbot:c2c:..."` | + +**CLI 命令示例(一次性提醒):** + +```bash +exec({ + command: 'openclaw cron add --name "喝水提醒" --at "30s" --session isolated --wake now --delete-after-run --announce --channel qqbot --to "qqbot:c2c:0DEBF031A9738F49D0194257976D7BAE" --message "你是一个暖心的提醒助手。请用温暖、有趣的方式提醒用户:该喝水了。要求:(1) 不要回复HEARTBEAT_OK (2) 不要解释你是谁 (3) 直接输出一条暖心的提醒消息 (4) 可以加一句简短的鸡汤或关怀的话 (5) 控制在2-3句话以内 (6) 用emoji点缀"' +}) +``` + +**CLI 命令示例(周期提醒):** + +```bash +exec({ + command: 'openclaw cron add --name "打卡提醒" --cron "0 8 * * *" --tz "Asia/Shanghai" --session isolated --wake now --announce --channel qqbot --to "qqbot:c2c:0DEBF031A9738F49D0194257976D7BAE" --message "你是一个暖心的提醒助手。请用温暖、有趣的方式提醒用户:该打卡了。要求:(1) 不要回复HEARTBEAT_OK (2) 不要解释你是谁 (3) 直接输出一条暖心的提醒消息 (4) 可以加一句简短的鸡汤或关怀的话 (5) 控制在2-3句话以内 (6) 用emoji点缀"' +}) +``` + +**查询提醒(CLI):** + +```bash +exec({ command: 'openclaw cron list --json' }) +``` + +**删除提醒(CLI):** + +```bash +exec({ command: 'openclaw cron rm ' }) +``` + +**⚠️ CLI 时间格式特殊说明:** + +- `--at` 参数支持: + - 相对时间:`"30s"`, `"5m"`, `"1h"`(推荐用于短时间提醒) + - ISO 时间:`"2026-03-14T10:00:00Z"` + - ❌ 不支持:毫秒时间戳(如 `1770734300000`) + +- JSON API 的 `schedule.atMs` 必须是毫秒时间戳,需要自己计算 +- CLI 的 `--at` 可以直接用 `"30s"` 这样的相对时间,更方便 + +**如何选择?** +1. 优先使用 `cron` 工具(如果可用) +2. 如果 `cron` 工具不可用,用 `exec` 执行 CLI 命令 +3. 可以通过 `openclaw cron add --help` 查看完整参数列表 + +--- + ## 🤖 AI 决策指南 ### 时间确认规则 From 65b8e3bcebccf7076c2b59ca7684b882df004eb0 Mon Sep 17 00:00:00 2001 From: sliverp Date: Sat, 14 Mar 2026 18:17:35 +0800 Subject: [PATCH 4/4] =?UTF-8?q?docs(changelog):=20=E6=B7=BB=E5=8A=A0=201.6?= =?UTF-8?q?.1=20=E7=89=88=E6=9C=AC=E6=9B=B4=E6=96=B0=E6=97=A5=E5=BF=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/changelog/1.6.1.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/changelog/1.6.1.md b/docs/changelog/1.6.1.md index a062054..97b6cb4 100644 --- a/docs/changelog/1.6.1.md +++ b/docs/changelog/1.6.1.md @@ -11,6 +11,10 @@ ## English +### ⬆️ Improvements + +- **Improved cron task execution accuracy**: Enhanced the execution precision of scheduled tasks (cron skill) for more accurate trigger timing. + ### ✨ New - **`/stop` urgent command support** (PR #134 by [@jerryliang122](https://github.com/jerryliang122)): When a user sends `/stop`, the command is executed immediately without entering the message queue. All pending queued messages for that user are also cleared, enabling instant interruption of ongoing AI conversations.