@cxyhhhhh/dsh-qqbot 0.3.0-dev.202608160954 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (176) hide show
  1. package/.orange-ci.yml +2 -68
  2. package/CHANGELOG.md +15 -0
  3. package/README.md +34 -14
  4. package/README_EN.md +34 -14
  5. package/cordis.patch.yml +1 -1
  6. package/cordis.yml +46 -3
  7. package/dist/commands/help.d.ts +6 -7
  8. package/dist/commands/help.d.ts.map +1 -1
  9. package/dist/commands/help.js +23 -7
  10. package/dist/commands/help.js.map +1 -1
  11. package/dist/commands/index.d.ts +7 -5
  12. package/dist/commands/index.d.ts.map +1 -1
  13. package/dist/commands/index.js +12 -12
  14. package/dist/commands/index.js.map +1 -1
  15. package/dist/commands/misc.d.ts +9 -7
  16. package/dist/commands/misc.d.ts.map +1 -1
  17. package/dist/commands/misc.js +20 -5
  18. package/dist/commands/misc.js.map +1 -1
  19. package/dist/commands/model.d.ts +3 -4
  20. package/dist/commands/model.d.ts.map +1 -1
  21. package/dist/commands/model.js +8 -7
  22. package/dist/commands/model.js.map +1 -1
  23. package/dist/commands/preset.d.ts +8 -0
  24. package/dist/commands/preset.d.ts.map +1 -0
  25. package/dist/commands/preset.js +52 -0
  26. package/dist/commands/preset.js.map +1 -0
  27. package/dist/commands/session.d.ts +11 -7
  28. package/dist/commands/session.d.ts.map +1 -1
  29. package/dist/commands/session.js +29 -13
  30. package/dist/commands/session.js.map +1 -1
  31. package/dist/commands/status.d.ts +3 -4
  32. package/dist/commands/status.d.ts.map +1 -1
  33. package/dist/commands/status.js +2 -1
  34. package/dist/commands/status.js.map +1 -1
  35. package/dist/commands/types.d.ts +9 -2
  36. package/dist/commands/types.d.ts.map +1 -1
  37. package/dist/config.d.ts +38 -0
  38. package/dist/config.d.ts.map +1 -1
  39. package/dist/config.js +35 -1
  40. package/dist/config.js.map +1 -1
  41. package/dist/features/answer-parser.d.ts +9 -0
  42. package/dist/features/answer-parser.d.ts.map +1 -0
  43. package/dist/features/answer-parser.js +23 -0
  44. package/dist/features/answer-parser.js.map +1 -0
  45. package/dist/features/approval-channel.d.ts +74 -0
  46. package/dist/features/approval-channel.d.ts.map +1 -0
  47. package/dist/features/approval-channel.js +142 -0
  48. package/dist/features/approval-channel.js.map +1 -0
  49. package/dist/features/approval-renderer.d.ts +18 -0
  50. package/dist/features/approval-renderer.d.ts.map +1 -0
  51. package/dist/features/approval-renderer.js +52 -0
  52. package/dist/features/approval-renderer.js.map +1 -0
  53. package/dist/features/button-utils.d.ts +33 -0
  54. package/dist/features/button-utils.d.ts.map +1 -0
  55. package/dist/features/button-utils.js +27 -0
  56. package/dist/features/button-utils.js.map +1 -0
  57. package/dist/features/history-store.d.ts.map +1 -1
  58. package/dist/features/history-store.js +0 -1
  59. package/dist/features/history-store.js.map +1 -1
  60. package/dist/features/question-channel.d.ts +96 -0
  61. package/dist/features/question-channel.d.ts.map +1 -0
  62. package/dist/features/question-channel.js +234 -0
  63. package/dist/features/question-channel.js.map +1 -0
  64. package/dist/features/question-renderer.d.ts +20 -0
  65. package/dist/features/question-renderer.d.ts.map +1 -0
  66. package/dist/features/question-renderer.js +70 -0
  67. package/dist/features/question-renderer.js.map +1 -0
  68. package/dist/gateway/bootstrap.d.ts +3 -3
  69. package/dist/gateway/bootstrap.d.ts.map +1 -1
  70. package/dist/gateway/bootstrap.js +74 -8
  71. package/dist/gateway/bootstrap.js.map +1 -1
  72. package/dist/gateway/index.d.ts +2 -2
  73. package/dist/gateway/index.js +2 -2
  74. package/dist/gateway/middleware-setup.d.ts +3 -3
  75. package/dist/gateway/middleware-setup.d.ts.map +1 -1
  76. package/dist/gateway/middleware-setup.js +9 -7
  77. package/dist/gateway/middleware-setup.js.map +1 -1
  78. package/dist/index.d.ts +2 -2
  79. package/dist/index.js +4 -4
  80. package/dist/media/media-cleaner.d.ts +19 -0
  81. package/dist/media/media-cleaner.d.ts.map +1 -0
  82. package/dist/media/media-cleaner.js +81 -0
  83. package/dist/media/media-cleaner.js.map +1 -0
  84. package/dist/media/send-file-tool.d.ts +35 -0
  85. package/dist/media/send-file-tool.d.ts.map +1 -0
  86. package/dist/media/send-file-tool.js +150 -0
  87. package/dist/media/send-file-tool.js.map +1 -0
  88. package/dist/media/vision-tool.d.ts +16 -0
  89. package/dist/media/vision-tool.d.ts.map +1 -0
  90. package/dist/media/vision-tool.js +241 -0
  91. package/dist/media/vision-tool.js.map +1 -0
  92. package/dist/middleware/attachment.d.ts +3 -3
  93. package/dist/middleware/attachment.d.ts.map +1 -1
  94. package/dist/middleware/attachment.js +17 -4
  95. package/dist/middleware/attachment.js.map +1 -1
  96. package/dist/middleware/question-answer.d.ts +10 -0
  97. package/dist/middleware/question-answer.d.ts.map +1 -0
  98. package/dist/middleware/question-answer.js +19 -0
  99. package/dist/middleware/question-answer.js.map +1 -0
  100. package/dist/model/index.d.ts +4 -4
  101. package/dist/model/index.js +3 -3
  102. package/dist/model/model-resolver.d.ts +27 -13
  103. package/dist/model/model-resolver.d.ts.map +1 -1
  104. package/dist/model/model-resolver.js +82 -27
  105. package/dist/model/model-resolver.js.map +1 -1
  106. package/dist/model/prefs-store.d.ts +6 -1
  107. package/dist/model/prefs-store.d.ts.map +1 -1
  108. package/dist/model/prefs-store.js +25 -1
  109. package/dist/model/prefs-store.js.map +1 -1
  110. package/dist/model/settings-reader.d.ts +1 -1
  111. package/dist/session/idle-evictor.d.ts +2 -2
  112. package/dist/session/idle-evictor.d.ts.map +1 -1
  113. package/dist/session/idle-evictor.js +1 -1
  114. package/dist/session/idle-evictor.js.map +1 -1
  115. package/dist/session/index.d.ts +3 -3
  116. package/dist/session/index.d.ts.map +1 -1
  117. package/dist/session/index.js +2 -2
  118. package/dist/session/session-manager.d.ts +67 -9
  119. package/dist/session/session-manager.d.ts.map +1 -1
  120. package/dist/session/session-manager.js +216 -20
  121. package/dist/session/session-manager.js.map +1 -1
  122. package/dist/session/types.d.ts +47 -1
  123. package/dist/session/types.d.ts.map +1 -1
  124. package/dist/shared/index.d.ts +3 -3
  125. package/dist/shared/index.d.ts.map +1 -1
  126. package/dist/shared/index.js +3 -3
  127. package/dist/shared/index.js.map +1 -1
  128. package/dist/shared/send-helper.js +1 -1
  129. package/dist/shared/utils.d.ts +2 -0
  130. package/dist/shared/utils.d.ts.map +1 -1
  131. package/dist/shared/utils.js +2 -2
  132. package/dist/shared/utils.js.map +1 -1
  133. package/dist/transport/attachment.d.ts +18 -7
  134. package/dist/transport/attachment.d.ts.map +1 -1
  135. package/dist/transport/attachment.js +77 -30
  136. package/dist/transport/attachment.js.map +1 -1
  137. package/dist/transport/inbound.d.ts +5 -4
  138. package/dist/transport/inbound.d.ts.map +1 -1
  139. package/dist/transport/inbound.js +120 -80
  140. package/dist/transport/inbound.js.map +1 -1
  141. package/dist/transport/index.d.ts +4 -4
  142. package/dist/transport/index.js +4 -4
  143. package/dist/transport/msgid-cache.d.ts +23 -0
  144. package/dist/transport/msgid-cache.d.ts.map +1 -0
  145. package/dist/transport/msgid-cache.js +57 -0
  146. package/dist/transport/msgid-cache.js.map +1 -0
  147. package/dist/transport/outbound-buffer.d.ts +9 -6
  148. package/dist/transport/outbound-buffer.d.ts.map +1 -1
  149. package/dist/transport/outbound-buffer.js +5 -5
  150. package/dist/transport/outbound-buffer.js.map +1 -1
  151. package/dist/transport/outbound.d.ts +9 -9
  152. package/dist/transport/outbound.d.ts.map +1 -1
  153. package/dist/transport/outbound.js +7 -7
  154. package/dist/transport/outbound.js.map +1 -1
  155. package/dist/transport/reply-limiter.d.ts +31 -0
  156. package/dist/transport/reply-limiter.d.ts.map +1 -0
  157. package/dist/transport/reply-limiter.js +50 -0
  158. package/dist/transport/reply-limiter.js.map +1 -0
  159. package/dist/transport/reply-target.d.ts +29 -0
  160. package/dist/transport/reply-target.d.ts.map +1 -0
  161. package/dist/transport/reply-target.js +55 -0
  162. package/dist/transport/reply-target.js.map +1 -0
  163. package/dist/transport/streaming-writer.d.ts +3 -3
  164. package/dist/transport/streaming-writer.d.ts.map +1 -1
  165. package/dist/transport/streaming-writer.js +1 -1
  166. package/dist/transport/streaming-writer.js.map +1 -1
  167. package/dist/transport/tool-presenter.d.ts +0 -1
  168. package/dist/transport/tool-presenter.d.ts.map +1 -1
  169. package/dist/transport/tool-presenter.js +0 -1
  170. package/dist/transport/tool-presenter.js.map +1 -1
  171. package/dist/types.d.ts +9 -15
  172. package/dist/types.d.ts.map +1 -1
  173. package/docs/assets/qrcode.png +0 -0
  174. package/package.json +17 -1
  175. package/a.txt +0 -14
  176. package/tiezi.md +0 -34
package/.orange-ci.yml CHANGED
@@ -1,68 +1,2 @@
1
- $:
2
- tag_push:
3
- - services:
4
- - docker
5
- docker:
6
- image: node:24
7
- runner:
8
- network: devnet
9
- stages:
10
- - name: 安装依赖
11
- script: npm install
12
- - name: 构建项目
13
- script: npm run build
14
- - name: 配置 npm 官方源
15
- script: npm config set registry https://registry.npmjs.org
16
- - name: 配置 token
17
- imports: https://git.woa.com/qq-ai/web/secret/blob/master/envs/npm/npmjs.txt
18
- script: npm config set //registry.npmjs.org/:_authToken=$NPM_TOKEN
19
- - name: 设置 npm 包版本号
20
- script: npm version ${ORANGE_BRANCH} --no-git-tag-version --allow-same-version
21
- - name: 发布 npm 包
22
- script: npm publish --access public
23
- - name: 生成通知
24
- script: echo "@tencent-connect/dsh-qqbot@${ORANGE_BRANCH} 发布成功" > message.txt
25
- - name: 发送通知
26
- type: wework:message
27
- options:
28
- fromFile: message.txt
29
-
30
- # ── master 分支:MR 检查 ──
31
- master:
32
- merge_request:
33
- - docker:
34
- image: node:24
35
- wework:
36
- silent: true
37
- stages:
38
- - name: 安装依赖
39
- script: npm install
40
- - name: TypeScript 类型检查
41
- script: npx tsc --noEmit
42
-
43
- # ── feat/fix 分支 push:内网发布 dev 版本 ──
44
- (feat|fix)/**:
45
- push:
46
- - docker:
47
- image: node:24
48
- runner:
49
- network: devnet
50
- stages:
51
- - name: 安装依赖
52
- script: npm install
53
- - name: 构建项目
54
- script: npm run build
55
- - name: 设置测试包名
56
- script: npm run ci:prepare-test-pkg
57
- - name: 设置测试版本
58
- script: npm version "0.0.0-dev.${ORANGE_COMMIT_SHORT}" --no-git-tag-version
59
- - name: 发布 npm 包
60
- image: tencentcom/npm:latest
61
- imports: https://git.woa.com/qq-ai/web/secret/blob/master/envs/npm/public.txt
62
- settings:
63
- username: $USER
64
- password: $PWD
65
- email: $EMAIL
66
- registry: https://mirrors.tencent.com/npm/
67
- folder: ./
68
- tag: dev
1
+ include:
2
+ - https://git.woa.com/qq-ai/web/secret/blob/master/ci/tencent-connect/dsh-qqbot.yml
package/CHANGELOG.md CHANGED
@@ -4,6 +4,21 @@
4
4
 
5
5
  格式遵循 [Keep a Changelog](https://keepachangelog.com/zh-CN/1.0.0/)。
6
6
 
7
+ ## [0.4.0] - 2026-08-16
8
+
9
+ ### 新功能
10
+
11
+ - **扫码链接**:二维码显示异常时,可直接点击终端输出的链接,在浏览器中完成扫码。
12
+
13
+ ### 体验优化
14
+
15
+ - 支持 Windows 平台自动保存扫码凭据(此前会因路径问题失效)。
16
+ - 凭据自动保存失败时,会明确引导手动配置,不再静默丢失已有配置。
17
+
18
+ ### 文档
19
+
20
+ - 新增扫码示意图与升级引导。
21
+
7
22
  ## [0.3.0] - 2026-08-15
8
23
 
9
24
  ### 新功能
package/README.md CHANGED
@@ -1,8 +1,19 @@
1
- # @tencent-connect/dsh-qqbot
1
+ <div align="center">
2
2
 
3
- 基于 [deepseek-harness](https://github.com/deepseek-ai/deepseek-harness) (dsh) 的 QQ Bot IM 插件,将 QQ 消息平台作为 dsh agent 的前端协议驱动。
3
+ <img width="120" src="https://img.shields.io/badge/🤖-QQ_Bot-blue?style=for-the-badge" alt="QQ Bot" />
4
4
 
5
- 中文 | [English](./README_EN.md)
5
+ **基于 [deepseek-harness](https://github.com/deepseek-ai/deepseek-harness) (dsh) 的 QQ Bot 插件,将 DeepSeek AI 助手接入 QQ 私聊与群聊。**
6
+
7
+ [![npm version](https://img.shields.io/npm/v/@tencent-connect/dsh-qqbot)](https://www.npmjs.com/package/@tencent-connect/dsh-qqbot)
8
+ [![License](https://img.shields.io/badge/license-MIT-green)](./LICENSE)
9
+ [![GitHub stars](https://img.shields.io/github/stars/tencent-connect/dsh-qqbot)](https://github.com/tencent-connect/dsh-qqbot)
10
+ [![QQ Bot](https://img.shields.io/badge/QQ_Bot-API_v2-red)](https://bot.q.qq.com/wiki/)
11
+
12
+ <br/>
13
+
14
+ **[English](./README_EN.md) | 简体中文**
15
+
16
+ </div>
6
17
 
7
18
  ## 架构
8
19
 
@@ -19,14 +30,18 @@ QQ 用户 → QQ WebSocket → dsh-im-qqbot → ctx.agents → dsh agent loop
19
30
 
20
31
  ```bash
21
32
  # 安装到 profile
22
- dsh plugin --profile qqbot add @tencent-connect/dsh-qqbot
33
+ npx @deepseek-ai/dsh plugin --profile qqbot add @tencent-connect/dsh-qqbot
23
34
 
24
35
  # 启动
25
- dsh --profile qqbot
36
+ npx @deepseek-ai/dsh --profile qqbot
26
37
  ```
27
38
 
28
39
  首次启动时,插件检测到凭据未配置会自动进入扫码引导:终端输出二维码 → 手机 QQ 扫码绑定 → 凭据自动保存到 profile,后续启动无需再次扫码。
29
40
 
41
+ <img src="./docs/assets/qrcode.png" alt="二维码扫码示意图" width="280" />
42
+
43
+ > **提示**:建议升级至 `0.4.0` 以上版本扫码,支持点击链接在浏览器打开,避免部分终端二维码渲染错位的问题。
44
+
30
45
  ### 方式二:本地路径安装
31
46
 
32
47
  ```bash
@@ -35,19 +50,18 @@ cd /path/to/dsh-qqbot
35
50
  pnpm install && pnpm build
36
51
 
37
52
  # 安装到 profile(本地路径)
38
- dsh plugin --profile qqbot add /path/to/dsh-qqbot
53
+ npx @deepseek-ai/dsh plugin --profile qqbot add /path/to/dsh-qqbot
39
54
 
40
55
  # 启动
41
56
  export QQBOT_APPID="你的AppID" QQBOT_SECRET="你的AppSecret"
42
- dsh --profile qqbot
57
+ npx @deepseek-ai/dsh --profile qqbot
43
58
  ```
44
59
 
45
60
  ### 方式三:--patch 开发模式
46
61
 
47
62
  ```bash
48
- cd /path/to/deepseek-harness
49
63
  export QQBOT_APPID="你的AppID" QQBOT_SECRET="你的AppSecret"
50
- pnpm dsh web --patch /path/to/dsh-qqbot/cordis.dev.yml
64
+ npx @deepseek-ai/dsh web --patch /path/to/dsh-qqbot/cordis.dev.yml
51
65
  ```
52
66
 
53
67
  ## 配置项
@@ -65,14 +79,20 @@ pnpm dsh web --patch /path/to/dsh-qqbot/cordis.dev.yml
65
79
  | `directPrompt` | string | - | 私聊额外 system prompt |
66
80
  | `textChunkLimit` | number | `4500` | 单条消息最大字符数 |
67
81
  | `sessionIdleTimeout` | number | `1800000` | 会话闲置超时(ms),默认 30 分钟 |
82
+ | `askTimeoutMs` | number | `300000` | 待答问题超时(ms),默认 5 分钟(ask_user_question) |
68
83
  | `debug` | boolean | `false` | 调试模式 |
69
84
 
70
85
  ## 内置命令
71
86
 
72
87
  | 命令 | 说明 |
73
88
  |------|------|
74
- | `/bot-reset` | 重置当前会话(清除上下文) |
75
- | `/bot-model` | 查看或切换模型 |
89
+ | `/new`(别名 `/reset` `/clear`) | 开始新会话(清空上下文) |
90
+ | `/compact` | 压缩会话历史(摘要替换旧记录,保留上下文) |
91
+ | `/model` | 查看或切换模型 |
92
+ | `/preset` | 查看或切换 agent preset(新会话生效) |
93
+ | `/stop` | 中止当前生成 |
94
+ | `/bot-ping` | 连通性测试 |
95
+ | `/bot-version` | 查看版本信息 |
76
96
  | `/bot-status` | 查看当前会话状态 |
77
97
  | `/bot-help` | 查看所有指令 |
78
98
 
@@ -118,6 +138,7 @@ sessionKey: `qqbot:${appId}:${scope}:${peerId}`,由 SHA-256 确定性派生 Se
118
138
  - **Preset 支持** — 可通过 `agent-presets` 服务挂载预设(工具集、prompt 等)
119
139
  - **闲置回收** — 超时自动 dispose Agent,防止内存泄漏
120
140
  - **Markdown 输出** — 回复以 Markdown 格式发送,支持代码块/表格感知切分
141
+ - **问答互动** — 支持 `ask_user_question`,单选生成内联按钮(点一个其余变灰)、多选回复编号,逐题推进 + 问题级超时
121
142
 
122
143
  ## 本地开发
123
144
 
@@ -131,10 +152,9 @@ pnpm build
131
152
  # 开发模式(watch)
132
153
  pnpm dev
133
154
 
134
- # 用 --patch 方式调试(在 dsh monorepo 中)
135
- cd /path/to/deepseek-harness
155
+ # 用 --patch 方式调试
136
156
  export QQBOT_APPID="xxx" QQBOT_SECRET="xxx"
137
- pnpm dsh web --patch /path/to/dsh-qqbot/cordis.dev.yml
157
+ npx @deepseek-ai/dsh web --patch /path/to/dsh-qqbot/cordis.dev.yml
138
158
  ```
139
159
 
140
160
  ## License
package/README_EN.md CHANGED
@@ -1,8 +1,19 @@
1
- # @tencent-connect/dsh-qqbot
1
+ <div align="center">
2
2
 
3
- A QQ Bot IM plugin for [deepseek-harness](https://github.com/deepseek-ai/deepseek-harness) (dsh), driving the dsh agent loop with the QQ messaging platform as the frontend protocol.
3
+ <img width="120" src="https://img.shields.io/badge/🤖-QQ_Bot-blue?style=for-the-badge" alt="QQ Bot" />
4
4
 
5
- [中文文档](./README.md) | English
5
+ **A QQ Bot plugin for [deepseek-harness](https://github.com/deepseek-ai/deepseek-harness) (dsh), connecting DeepSeek AI assistants to QQ private and group chats.**
6
+
7
+ [![npm version](https://img.shields.io/npm/v/@tencent-connect/dsh-qqbot)](https://www.npmjs.com/package/@tencent-connect/dsh-qqbot)
8
+ [![License](https://img.shields.io/badge/license-MIT-green)](./LICENSE)
9
+ [![GitHub stars](https://img.shields.io/github/stars/tencent-connect/dsh-qqbot)](https://github.com/tencent-connect/dsh-qqbot)
10
+ [![QQ Bot](https://img.shields.io/badge/QQ_Bot-API_v2-red)](https://bot.q.qq.com/wiki/)
11
+
12
+ <br/>
13
+
14
+ **[简体中文](./README.md) | English**
15
+
16
+ </div>
6
17
 
7
18
  ## Architecture
8
19
 
@@ -19,14 +30,18 @@ QQ User → QQ WebSocket → dsh-im-qqbot → ctx.agents → dsh agent loop →
19
30
 
20
31
  ```bash
21
32
  # Add to a profile
22
- dsh plugin --profile qqbot add @tencent-connect/dsh-qqbot
33
+ npx @deepseek-ai/dsh plugin --profile qqbot add @tencent-connect/dsh-qqbot
23
34
 
24
35
  # Start
25
- dsh --profile qqbot
36
+ npx @deepseek-ai/dsh --profile qqbot
26
37
  ```
27
38
 
28
39
  On first launch, the plugin detects missing credentials and automatically starts the QR flow: a QR code is printed in the terminal → scan it with the QQ mobile app → credentials are saved to the profile, so subsequent launches require no re-scan.
29
40
 
41
+ <img src="./docs/assets/qrcode.png" alt="QR code scan example" width="280" />
42
+
43
+ > **Note**: Upgrade to `0.4.0` or later for browser-link scanning, which avoids QR code misalignment in some terminals.
44
+
30
45
  ### Method 2: Local path
31
46
 
32
47
  ```bash
@@ -35,19 +50,18 @@ cd /path/to/dsh-qqbot
35
50
  pnpm install && pnpm build
36
51
 
37
52
  # Add to a profile (local path)
38
- dsh plugin --profile qqbot add /path/to/dsh-qqbot
53
+ npx @deepseek-ai/dsh plugin --profile qqbot add /path/to/dsh-qqbot
39
54
 
40
55
  # Start
41
56
  export QQBOT_APPID="yourAppID" QQBOT_SECRET="yourAppSecret"
42
- dsh --profile qqbot
57
+ npx @deepseek-ai/dsh --profile qqbot
43
58
  ```
44
59
 
45
60
  ### Method 3: --patch dev mode
46
61
 
47
62
  ```bash
48
- cd /path/to/deepseek-harness
49
63
  export QQBOT_APPID="yourAppID" QQBOT_SECRET="yourAppSecret"
50
- pnpm dsh web --patch /path/to/dsh-qqbot/cordis.dev.yml
64
+ npx @deepseek-ai/dsh web --patch /path/to/dsh-qqbot/cordis.dev.yml
51
65
  ```
52
66
 
53
67
  ## Configuration
@@ -65,14 +79,20 @@ pnpm dsh web --patch /path/to/dsh-qqbot/cordis.dev.yml
65
79
  | `directPrompt` | string | - | Extra system prompt for direct chats |
66
80
  | `textChunkLimit` | number | `4500` | Max chars per message |
67
81
  | `sessionIdleTimeout` | number | `1800000` | Session idle timeout (ms), default 30 min |
82
+ | `askTimeoutMs` | number | `300000` | Question timeout (ms), default 5 min (ask_user_question) |
68
83
  | `debug` | boolean | `false` | Debug mode |
69
84
 
70
85
  ## Built-in Commands
71
86
 
72
87
  | Command | Description |
73
88
  |------|------|
74
- | `/bot-reset` | Reset the current session (clear context) |
75
- | `/bot-model` | View or switch model |
89
+ | `/new` (aliases `/reset` `/clear`) | Start a new session (clear context) |
90
+ | `/compact` | Compact session history (replace old records with a summary) |
91
+ | `/model` | View or switch model |
92
+ | `/preset` | View or switch agent preset (applies to new sessions) |
93
+ | `/stop` | Abort the current generation |
94
+ | `/bot-ping` | Connectivity test |
95
+ | `/bot-version` | View version info |
76
96
  | `/bot-status` | View current session status |
77
97
  | `/bot-help` | View all commands |
78
98
 
@@ -118,6 +138,7 @@ Resolution strategy: in-process reuse → persisted resume → fresh create.
118
138
  - **Preset support** — mount presets (toolkits, prompts, etc.) via the `agent-presets` service
119
139
  - **Idle eviction** — auto-dispose Agents on timeout to prevent memory leaks
120
140
  - **Markdown output** — replies sent as Markdown with code-block/table-aware chunking
141
+ - **Question interaction** — supports `ask_user_question` with inline keyboard buttons (mutually exclusive) or numbered replies, one question at a time with timeout
121
142
 
122
143
  ## Local Development
123
144
 
@@ -131,10 +152,9 @@ pnpm build
131
152
  # Dev mode (watch)
132
153
  pnpm dev
133
154
 
134
- # Debug via --patch (inside the dsh monorepo)
135
- cd /path/to/deepseek-harness
155
+ # Debug via --patch
136
156
  export QQBOT_APPID="xxx" QQBOT_SECRET="xxx"
137
- pnpm dsh web --patch /path/to/dsh-qqbot/cordis.dev.yml
157
+ npx @deepseek-ai/dsh web --patch /path/to/dsh-qqbot/cordis.dev.yml
138
158
  ```
139
159
 
140
160
  ## License
package/cordis.patch.yml CHANGED
@@ -22,7 +22,7 @@
22
22
  textChunkLimit: 4500
23
23
  sessionIdleTimeout: 1800000
24
24
  maxQueue: 20
25
- processingTimeoutMs: 120000
25
+ processingTimeoutMs: 1800000
26
26
  historyLimit: 10
27
27
  access:
28
28
  c2cMode: open
package/cordis.yml CHANGED
@@ -7,6 +7,8 @@
7
7
  # QQBOT_SECRET - QQ Bot AppSecret
8
8
  # DEEPSEEK_API_KEY - DeepSeek API Key
9
9
  # DSH_CWD - Agent 工作目录(可选)
10
+ # HUNYUAN_API_KEY - 视觉模型 API Key(qqbot_describe_image 工具,hunyuan-vision)
11
+ # DSH_PRESET_ROOT - 系统预置 preset 目录(可选,默认 ./apps/cli/config/agent-presets)
10
12
 
11
13
  # ── 核心 spine ──
12
14
  - id: sessions
@@ -21,15 +23,52 @@
21
23
  - id: system-prompt
22
24
  name: '@deepseek-ai/dsh-system-prompt'
23
25
 
26
+ - id: approval
27
+ name: '@deepseek-ai/dsh-user-approval'
28
+ config:
29
+ policy: !!js "process.platform === 'win32' ? 'never' : ((process.env.DSH_PERMISSION_MODE ?? 'workspace-write') === 'danger-full-access' ? 'never' : 'ask')"
30
+
24
31
  - id: tools
25
32
  name: '@deepseek-ai/dsh-tools'
26
33
 
34
+ # ── Agent Preset 服务(/preset 命令切换 preset 依赖) ──
35
+ - id: agent-presets
36
+ name: '@deepseek-ai/dsh-agent-presets'
37
+ config:
38
+ default: standard
39
+ roots:
40
+ # 系统预置 preset 目录(deepseek-harness 的 apps/cli/config/agent-presets,含 standard/code/cordis/minimal)
41
+ - path: ${DSH_PRESET_ROOT:-./apps/cli/config/agent-presets}
42
+ trust: system
43
+ # includeUserRoot 默认 true:额外加载 $DSH_HOME/.agent-presets(用户自定义 preset)
44
+
45
+ # ── 附件存储(describe_image 工具的 attachments.saveImage 依赖) ──
46
+ - id: attachment-local
47
+ name: '@deepseek-ai/dsh-attachment-local'
48
+
27
49
  # ── LLM 适配器 ──
28
50
  - id: llm-deepseek
29
51
  name: '@deepseek-ai/dsh-llm-deepseek'
30
52
  config:
31
53
  apiKey: ${DEEPSEEK_API_KEY}
32
54
 
55
+ # 视觉模型适配器(qqbot_describe_image 工具用 llm.stream 调多模态模型)
56
+ - id: llm-pi-ai
57
+ name: '@deepseek-ai/dsh-llm-pi-ai'
58
+ config:
59
+ providers:
60
+ hunyuan:
61
+ displayName: Hunyuan Vision
62
+ apiKeyEnv: HUNYUAN_API_KEY
63
+ api: openai-completions
64
+ baseURL: https://api.hunyuan.cloud.tencent.com/v1
65
+ defaultInput: [text, image]
66
+ models:
67
+ - id: hunyuan-vision
68
+ name: Hunyuan Vision
69
+ contextWindow: 32768
70
+ maxTokens: 4096
71
+
33
72
  # ── 执行能力(按需启用) ──
34
73
  - id: tool-bash
35
74
  name: '@deepseek-ai/dsh-tool-bash'
@@ -55,15 +94,19 @@
55
94
 
56
95
  # ── QQ Bot IM 驱动 ──
57
96
  - id: im-qqbot
58
- name: '@deepseek-ai/dsh-im-qqbot'
97
+ name: '@tencent-connect/dsh-qqbot'
59
98
  config:
60
99
  appId: ${QQBOT_APPID}
61
100
  appSecret: ${QQBOT_SECRET}
62
- transport: websocket
63
101
  provider: deepseek
64
102
  model: deepseek-chat
65
103
  cwd: ${DSH_CWD:-/tmp/dsh-qqbot}
66
- requireMention: false
104
+ requireMention: true
67
105
  textChunkLimit: 4500
68
106
  sessionIdleTimeout: 1800000
107
+ showToolResults: false
69
108
  debug: false
109
+ vision:
110
+ enabled: false
111
+ provider: '' # 视觉模型 provider(需与上方 llm-pi-ai 配置的路由一致,如 hunyuan)
112
+ model: '' # 视觉模型 id(如 hunyuan-vision)
@@ -1,11 +1,10 @@
1
1
  /**
2
- * /bot-help — 查看所有指令以及用途
2
+ * /bot-help — 查看所有指令,按「通用能力 / QQBot 特有」分组展示
3
3
  *
4
- * 参考 openclaw-qqbot 的 bot-help.ts:遍历所有非隐藏命令,
5
- * 用 <qqbot-cmd-input> 展示为可点击按钮,以 Markdown 格式发送。
4
+ * 通用能力:对应底层 dsh agent 能力(new/compact/model/stop),无前缀
5
+ * QQBot 特有:插件自身封装(bot-ping/bot-version/bot-status/bot-help),带 bot- 前缀
6
6
  */
7
- import type { SlashCommand } from '@tencent-connect/qqbot-nodejs';
8
- import type { CommandDeps } from './types.js';
9
- /** /bot-help — 查看所有指令以及用途 */
10
- export declare function helpCommand({ config }: CommandDeps, allCommands: () => SlashCommand[]): SlashCommand;
7
+ import type { CommandDeps, CategorizedCommand } from './types.ts';
8
+ /** /bot-help — 分组查看所有指令 */
9
+ export declare function helpCommand({ config }: CommandDeps, allCommands: () => CategorizedCommand[]): CategorizedCommand;
11
10
  //# sourceMappingURL=help.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"help.d.ts","sourceRoot":"","sources":["../../src/commands/help.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAClE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAG9C,6BAA6B;AAC7B,wBAAgB,WAAW,CAAC,EAAE,MAAM,EAAE,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,YAAY,EAAE,GAAG,YAAY,CAkBpG"}
1
+ {"version":3,"file":"help.d.ts","sourceRoot":"","sources":["../../src/commands/help.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAGlE,2BAA2B;AAC3B,wBAAgB,WAAW,CACzB,EAAE,MAAM,EAAE,EAAE,WAAW,EACvB,WAAW,EAAE,MAAM,kBAAkB,EAAE,GACtC,kBAAkB,CAoCpB"}
@@ -1,18 +1,34 @@
1
- import { sendMarkdownChunked } from '../shared/index.js';
2
- /** /bot-help — 查看所有指令以及用途 */
1
+ import { sendMarkdownChunked, PLUGIN_VERSION } from "../shared/index.js";
2
+ /** /bot-help — 分组查看所有指令 */
3
3
  export function helpCommand({ config }, allCommands) {
4
4
  return {
5
5
  name: 'bot-help',
6
- description: '查看所有指令以及用途',
6
+ category: 'qqbot',
7
+ description: '查看所有指令',
7
8
  handler: async (cmdCtx) => {
8
- const lines = ['### QQBot插件内置指令', ''];
9
+ const agentCmds = [];
10
+ const qqbotCmds = [];
9
11
  for (const cmd of allCommands()) {
10
- const name = Array.isArray(cmd.name) ? cmd.name[0] : cmd.name;
11
12
  if (cmd.hidden)
12
13
  continue;
13
- lines.push(`<qqbot-cmd-input text="/${name}" show="/${name}"/> ${cmd.description ?? ''}`);
14
+ (cmd.category === 'agent' ? agentCmds : qqbotCmds).push(cmd);
14
15
  }
15
- lines.push('', '> dsh-qqbot v0.1.0');
16
+ const render = (cmds) => {
17
+ const out = [];
18
+ for (const cmd of cmds) {
19
+ const name = Array.isArray(cmd.name) ? cmd.name[0] : cmd.name;
20
+ out.push(`<qqbot-cmd-input text="/${name}" show="/${name}"/> ${cmd.description ?? ''}`);
21
+ }
22
+ return out;
23
+ };
24
+ const lines = ['### 🤖 QQBot 指令', ''];
25
+ if (agentCmds.length > 0) {
26
+ lines.push('**通用能力**', '', ...render(agentCmds), '');
27
+ }
28
+ if (qqbotCmds.length > 0) {
29
+ lines.push('**插件内置指令**', '', ...render(qqbotCmds), '');
30
+ }
31
+ lines.push('', `> dsh-qqbot v${PLUGIN_VERSION}`);
16
32
  await sendMarkdownChunked(cmdCtx, lines.join('\n'), config.textChunkLimit);
17
33
  return { kind: 'noop' };
18
34
  },
@@ -1 +1 @@
1
- {"version":3,"file":"help.js","sourceRoot":"","sources":["../../src/commands/help.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAEzD,6BAA6B;AAC7B,MAAM,UAAU,WAAW,CAAC,EAAE,MAAM,EAAe,EAAE,WAAiC;IACpF,OAAO;QACL,IAAI,EAAE,UAAU;QAChB,WAAW,EAAE,YAAY;QACzB,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;YACxB,MAAM,KAAK,GAAG,CAAC,iBAAiB,EAAE,EAAE,CAAC,CAAC;YAEtC,KAAK,MAAM,GAAG,IAAI,WAAW,EAAE,EAAE,CAAC;gBAChC,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC;gBAC9D,IAAI,GAAG,CAAC,MAAM;oBAAE,SAAS;gBACzB,KAAK,CAAC,IAAI,CAAC,2BAA2B,IAAI,YAAY,IAAI,OAAO,GAAG,CAAC,WAAW,IAAI,EAAE,EAAE,CAAC,CAAC;YAC5F,CAAC;YAED,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,oBAAoB,CAAC,CAAC;YACrC,MAAM,mBAAmB,CAAC,MAAM,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,cAAc,CAAC,CAAC;YAC3E,OAAO,EAAE,IAAI,EAAE,MAAe,EAAE,CAAC;QACnC,CAAC;KACF,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"help.js","sourceRoot":"","sources":["../../src/commands/help.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEzE,2BAA2B;AAC3B,MAAM,UAAU,WAAW,CACzB,EAAE,MAAM,EAAe,EACvB,WAAuC;IAEvC,OAAO;QACL,IAAI,EAAE,UAAU;QAChB,QAAQ,EAAE,OAAO;QACjB,WAAW,EAAE,QAAQ;QACrB,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;YACxB,MAAM,SAAS,GAAyB,EAAE,CAAC;YAC3C,MAAM,SAAS,GAAyB,EAAE,CAAC;YAC3C,KAAK,MAAM,GAAG,IAAI,WAAW,EAAE,EAAE,CAAC;gBAChC,IAAI,GAAG,CAAC,MAAM;oBAAE,SAAS;gBACzB,CAAC,GAAG,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAC/D,CAAC;YAED,MAAM,MAAM,GAAG,CAAC,IAA0B,EAAY,EAAE;gBACtD,MAAM,GAAG,GAAa,EAAE,CAAC;gBACzB,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;oBACvB,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC;oBAC9D,GAAG,CAAC,IAAI,CAAC,2BAA2B,IAAI,YAAY,IAAI,OAAO,GAAG,CAAC,WAAW,IAAI,EAAE,EAAE,CAAC,CAAC;gBAC1F,CAAC;gBACD,OAAO,GAAG,CAAC;YACb,CAAC,CAAC;YAEF,MAAM,KAAK,GAAa,CAAC,iBAAiB,EAAE,EAAE,CAAC,CAAC;YAEhD,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACzB,KAAK,CAAC,IAAI,CAAC,UAAU,EAAE,EAAE,EAAE,GAAG,MAAM,CAAC,SAAS,CAAC,EAAE,EAAE,CAAC,CAAC;YACvD,CAAC;YACD,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACzB,KAAK,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,EAAE,GAAG,MAAM,CAAC,SAAS,CAAC,EAAE,EAAE,CAAC,CAAC;YACzD,CAAC;YAED,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,gBAAgB,cAAc,EAAE,CAAC,CAAC;YACjD,MAAM,mBAAmB,CAAC,MAAM,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,cAAc,CAAC,CAAC;YAC3E,OAAO,EAAE,IAAI,EAAE,MAAe,EAAE,CAAC;QACnC,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -1,13 +1,15 @@
1
1
  /**
2
2
  * 斜杠命令注册中心
3
3
  *
4
- * 每个命令拆分为独立文件,此处仅编排。参考 openclaw-qqbot 的
5
- * commands/index.ts 模式:工厂函数注入依赖,统一导出命令列表。
4
+ * 每个命令拆分为独立文件,此处仅编排。工厂函数注入依赖,统一导出命令列表。
5
+ *
6
+ * 命令按 category 分两类:
7
+ * - agent:底层 dsh agent 通用能力(new/compact/model/stop)
8
+ * - qqbot:插件自身特有(ping/version/status/help)
6
9
  */
7
- import type { SlashCommand } from '@tencent-connect/qqbot-nodejs';
8
- import type { CommandDeps } from './types.js';
10
+ import type { CommandDeps, CategorizedCommand } from './types.ts';
9
11
  /**
10
12
  * 构建标准命令列表
11
13
  */
12
- export declare function buildCommandList(deps: CommandDeps): SlashCommand[];
14
+ export declare function buildCommandList(deps: CommandDeps): CategorizedCommand[];
13
15
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/commands/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAClE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAO9C;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,WAAW,GAAG,YAAY,EAAE,CAmBlE"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/commands/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,KAAK,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAQlE;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,WAAW,GAAG,kBAAkB,EAAE,CAkBxE"}
@@ -1,24 +1,24 @@
1
- import { resetCommand, newCommand } from './session.js';
2
- import { modelCommand } from './model.js';
3
- import { statusCommand } from './status.js';
4
- import { helpCommand } from './help.js';
5
- import { pingCommand, versionCommand, stopCommand } from './misc.js';
1
+ import { newCommand, compactCommand } from "./session.js";
2
+ import { modelCommand } from "./model.js";
3
+ import { presetCommand } from "./preset.js";
4
+ import { statusCommand } from "./status.js";
5
+ import { helpCommand } from "./help.js";
6
+ import { pingCommand, versionCommand, stopCommand } from "./misc.js";
6
7
  /**
7
8
  * 构建标准命令列表
8
9
  */
9
10
  export function buildCommandList(deps) {
10
11
  const commands = [
11
- // 会话
12
- resetCommand(deps),
12
+ // 通用能力(底层 agent)
13
13
  newCommand(deps),
14
- // 模型
14
+ compactCommand(deps),
15
15
  modelCommand(deps),
16
- // 状态
17
- statusCommand(deps),
18
- // 杂项
16
+ presetCommand(deps),
17
+ stopCommand(deps),
18
+ // QQBot 特有
19
19
  pingCommand(),
20
20
  versionCommand(deps),
21
- stopCommand(),
21
+ statusCommand(deps),
22
22
  ];
23
23
  // help 需要访问完整列表(含自身),通过闭包惰性引用
24
24
  commands.push(helpCommand(deps, () => commands));
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/commands/index.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAErE;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAAC,IAAiB;IAChD,MAAM,QAAQ,GAAmB;QAC/B,KAAK;QACL,YAAY,CAAC,IAAI,CAAC;QAClB,UAAU,CAAC,IAAI,CAAC;QAChB,KAAK;QACL,YAAY,CAAC,IAAI,CAAC;QAClB,KAAK;QACL,aAAa,CAAC,IAAI,CAAC;QACnB,KAAK;QACL,WAAW,EAAE;QACb,cAAc,CAAC,IAAI,CAAC;QACpB,WAAW,EAAE;KACd,CAAC;IAEF,8BAA8B;IAC9B,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;IAEjD,OAAO,QAAQ,CAAC;AAClB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/commands/index.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAErE;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAAC,IAAiB;IAChD,MAAM,QAAQ,GAAyB;QACrC,iBAAiB;QACjB,UAAU,CAAC,IAAI,CAAC;QAChB,cAAc,CAAC,IAAI,CAAC;QACpB,YAAY,CAAC,IAAI,CAAC;QAClB,aAAa,CAAC,IAAI,CAAC;QACnB,WAAW,CAAC,IAAI,CAAC;QACjB,WAAW;QACX,WAAW,EAAE;QACb,cAAc,CAAC,IAAI,CAAC;QACpB,aAAa,CAAC,IAAI,CAAC;KACpB,CAAC;IAEF,8BAA8B;IAC9B,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;IAEjD,OAAO,QAAQ,CAAC;AAClB,CAAC"}
@@ -1,12 +1,14 @@
1
1
  /**
2
- * 杂项命令:/ping /version /stop
2
+ * 杂项命令
3
+ *
4
+ * - /bot-ping /bot-version:QQBot 插件特有(连通性测试、版本信息)
5
+ * - /stop:中止当前生成(对应底层 agent cancel,通用能力)
3
6
  */
4
- import type { SlashCommand } from '@tencent-connect/qqbot-nodejs';
5
- import type { CommandDeps } from './types.js';
7
+ import type { CommandDeps, CategorizedCommand } from './types.ts';
6
8
  /** /bot-ping — 连通性测试 */
7
- export declare function pingCommand(): SlashCommand;
9
+ export declare function pingCommand(): CategorizedCommand;
8
10
  /** /bot-version — 查看版本信息 */
9
- export declare function versionCommand({ manager }: CommandDeps): SlashCommand;
10
- /** /bot-stop — 中止当前生成(隐藏) */
11
- export declare function stopCommand(): SlashCommand;
11
+ export declare function versionCommand({ manager }: CommandDeps): CategorizedCommand;
12
+ /** /stop — 中止当前生成(隐藏) */
13
+ export declare function stopCommand({ manager }: CommandDeps): CategorizedCommand;
12
14
  //# sourceMappingURL=misc.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"misc.d.ts","sourceRoot":"","sources":["../../src/commands/misc.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAClE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C,wBAAwB;AACxB,wBAAgB,WAAW,IAAI,YAAY,CAM1C;AAED,4BAA4B;AAC5B,wBAAgB,cAAc,CAAC,EAAE,OAAO,EAAE,EAAE,WAAW,GAAG,YAAY,CAUrE;AAED,6BAA6B;AAC7B,wBAAgB,WAAW,IAAI,YAAY,CAO1C"}
1
+ {"version":3,"file":"misc.d.ts","sourceRoot":"","sources":["../../src/commands/misc.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAGlE,wBAAwB;AACxB,wBAAgB,WAAW,IAAI,kBAAkB,CAOhD;AAED,4BAA4B;AAC5B,wBAAgB,cAAc,CAAC,EAAE,OAAO,EAAE,EAAE,WAAW,GAAG,kBAAkB,CAW3E;AAED,yBAAyB;AACzB,wBAAgB,WAAW,CAAC,EAAE,OAAO,EAAE,EAAE,WAAW,GAAG,kBAAkB,CAoBxE"}
@@ -1,7 +1,9 @@
1
+ import { getScopePeer, PLUGIN_VERSION } from "../shared/index.js";
1
2
  /** /bot-ping — 连通性测试 */
2
3
  export function pingCommand() {
3
4
  return {
4
5
  name: 'bot-ping',
6
+ category: 'qqbot',
5
7
  description: '连通性测试',
6
8
  handler: () => 'pong 🏓',
7
9
  };
@@ -10,21 +12,34 @@ export function pingCommand() {
10
12
  export function versionCommand({ manager }) {
11
13
  return {
12
14
  name: 'bot-version',
15
+ category: 'qqbot',
13
16
  description: '查看版本信息',
14
17
  handler: () => {
15
18
  const current = manager.getEffectiveModel('c2c', '');
16
19
  const modelInfo = current ? `${current.provider}/${current.model}` : '宿主默认';
17
- return `dsh-qqbot v0.1.0 | model: ${modelInfo}`;
20
+ return `dsh-qqbot v${PLUGIN_VERSION} | model: ${modelInfo}`;
18
21
  },
19
22
  };
20
23
  }
21
- /** /bot-stop — 中止当前生成(隐藏) */
22
- export function stopCommand() {
24
+ /** /stop — 中止当前生成(隐藏) */
25
+ export function stopCommand({ manager }) {
23
26
  return {
24
- name: 'bot-stop',
27
+ name: 'stop',
28
+ category: 'agent',
25
29
  description: '中止当前生成',
26
30
  hidden: true,
27
- handler: () => ({ kind: 'noop' }),
31
+ handler: (cmdCtx) => {
32
+ const { scope, peerId } = getScopePeer(cmdCtx);
33
+ const record = manager.getSessionRecord(scope, peerId);
34
+ // 会话存在不等于正在生成:只有 agent 处于 running 才算有进行中的回复
35
+ if (record === undefined || record.agent.status !== 'running') {
36
+ return '当前没有进行中的生成';
37
+ }
38
+ // cancel 会让当前轮以 turn/end (kind=interrupted) 收尾,
39
+ // 出站侧据此 flush 已生成的文本并关闭流式会话。
40
+ record.agent.cancel({ kind: 'user' });
41
+ return '已中止 ⛔';
42
+ },
28
43
  };
29
44
  }
30
45
  //# sourceMappingURL=misc.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"misc.js","sourceRoot":"","sources":["../../src/commands/misc.ts"],"names":[],"mappings":"AAMA,wBAAwB;AACxB,MAAM,UAAU,WAAW;IACzB,OAAO;QACL,IAAI,EAAE,UAAU;QAChB,WAAW,EAAE,OAAO;QACpB,OAAO,EAAE,GAAG,EAAE,CAAC,SAAS;KACzB,CAAC;AACJ,CAAC;AAED,4BAA4B;AAC5B,MAAM,UAAU,cAAc,CAAC,EAAE,OAAO,EAAe;IACrD,OAAO;QACL,IAAI,EAAE,aAAa;QACnB,WAAW,EAAE,QAAQ;QACrB,OAAO,EAAE,GAAG,EAAE;YACZ,MAAM,OAAO,GAAG,OAAO,CAAC,iBAAiB,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;YACrD,MAAM,SAAS,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,QAAQ,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC;YAC5E,OAAO,6BAA6B,SAAS,EAAE,CAAC;QAClD,CAAC;KACF,CAAC;AACJ,CAAC;AAED,6BAA6B;AAC7B,MAAM,UAAU,WAAW;IACzB,OAAO;QACL,IAAI,EAAE,UAAU;QAChB,WAAW,EAAE,QAAQ;QACrB,MAAM,EAAE,IAAI;QACZ,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,CAAC;KAC3C,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"misc.js","sourceRoot":"","sources":["../../src/commands/misc.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAElE,wBAAwB;AACxB,MAAM,UAAU,WAAW;IACzB,OAAO;QACL,IAAI,EAAE,UAAU;QAChB,QAAQ,EAAE,OAAO;QACjB,WAAW,EAAE,OAAO;QACpB,OAAO,EAAE,GAAG,EAAE,CAAC,SAAS;KACzB,CAAC;AACJ,CAAC;AAED,4BAA4B;AAC5B,MAAM,UAAU,cAAc,CAAC,EAAE,OAAO,EAAe;IACrD,OAAO;QACL,IAAI,EAAE,aAAa;QACnB,QAAQ,EAAE,OAAO;QACjB,WAAW,EAAE,QAAQ;QACrB,OAAO,EAAE,GAAG,EAAE;YACZ,MAAM,OAAO,GAAG,OAAO,CAAC,iBAAiB,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;YACrD,MAAM,SAAS,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,QAAQ,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC;YAC5E,OAAO,cAAc,cAAc,aAAa,SAAS,EAAE,CAAC;QAC9D,CAAC;KACF,CAAC;AACJ,CAAC;AAED,yBAAyB;AACzB,MAAM,UAAU,WAAW,CAAC,EAAE,OAAO,EAAe;IAClD,OAAO;QACL,IAAI,EAAE,MAAM;QACZ,QAAQ,EAAE,OAAO;QACjB,WAAW,EAAE,QAAQ;QACrB,MAAM,EAAE,IAAI;QACZ,OAAO,EAAE,CAAC,MAAM,EAAE,EAAE;YAClB,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;YAC/C,MAAM,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;YACvD,4CAA4C;YAC5C,IAAI,MAAM,KAAK,SAAS,IAAI,MAAM,CAAC,KAAK,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;gBAC9D,OAAO,YAAY,CAAC;YACtB,CAAC;YAED,gDAAgD;YAChD,6BAA6B;YAC7B,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;YACtC,OAAO,OAAO,CAAC;QACjB,CAAC;KACF,CAAC;AACJ,CAAC"}