@z-qinghui/migpt-claw 1.0.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 (111) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +690 -0
  3. package/dist/index.d.ts +23 -0
  4. package/dist/index.js +33 -0
  5. package/dist/index.js.map +1 -0
  6. package/dist/setup-entry.d.ts +3 -0
  7. package/dist/setup-entry.js +7 -0
  8. package/dist/setup-entry.js.map +1 -0
  9. package/dist/src/channel.d.ts +10 -0
  10. package/dist/src/channel.js +444 -0
  11. package/dist/src/channel.js.map +1 -0
  12. package/dist/src/config.d.ts +125 -0
  13. package/dist/src/config.js +146 -0
  14. package/dist/src/config.js.map +1 -0
  15. package/dist/src/message.d.ts +51 -0
  16. package/dist/src/message.js +145 -0
  17. package/dist/src/message.js.map +1 -0
  18. package/dist/src/mi/account.d.ts +5 -0
  19. package/dist/src/mi/account.js +162 -0
  20. package/dist/src/mi/account.js.map +1 -0
  21. package/dist/src/mi/common.d.ts +15 -0
  22. package/dist/src/mi/common.js +80 -0
  23. package/dist/src/mi/common.js.map +1 -0
  24. package/dist/src/mi/index.d.ts +4 -0
  25. package/dist/src/mi/index.js +10 -0
  26. package/dist/src/mi/index.js.map +1 -0
  27. package/dist/src/mi/mina.d.ts +66 -0
  28. package/dist/src/mi/mina.js +225 -0
  29. package/dist/src/mi/mina.js.map +1 -0
  30. package/dist/src/mi/miot.d.ts +35 -0
  31. package/dist/src/mi/miot.js +168 -0
  32. package/dist/src/mi/miot.js.map +1 -0
  33. package/dist/src/mi/typing.d.ts +90 -0
  34. package/dist/src/mi/typing.js +1 -0
  35. package/dist/src/mi/typing.js.map +1 -0
  36. package/dist/src/onboarding.d.ts +5 -0
  37. package/dist/src/onboarding.js +118 -0
  38. package/dist/src/onboarding.js.map +1 -0
  39. package/dist/src/openclaw-plugin-sdk.d.d.ts +185 -0
  40. package/dist/src/openclaw-plugin-sdk.d.js +1 -0
  41. package/dist/src/openclaw-plugin-sdk.d.js.map +1 -0
  42. package/dist/src/outbound.d.ts +5 -0
  43. package/dist/src/outbound.js +108 -0
  44. package/dist/src/outbound.js.map +1 -0
  45. package/dist/src/runtime.d.ts +6 -0
  46. package/dist/src/runtime.js +15 -0
  47. package/dist/src/runtime.js.map +1 -0
  48. package/dist/src/service.d.ts +70 -0
  49. package/dist/src/service.js +200 -0
  50. package/dist/src/service.js.map +1 -0
  51. package/dist/src/speaker.d.ts +62 -0
  52. package/dist/src/speaker.js +211 -0
  53. package/dist/src/speaker.js.map +1 -0
  54. package/dist/src/tts/mimo.d.ts +50 -0
  55. package/dist/src/tts/mimo.js +214 -0
  56. package/dist/src/tts/mimo.js.map +1 -0
  57. package/dist/src/types.d.ts +30 -0
  58. package/dist/src/types.js +1 -0
  59. package/dist/src/types.js.map +1 -0
  60. package/dist/src/utils/codec.d.ts +31 -0
  61. package/dist/src/utils/codec.js +144 -0
  62. package/dist/src/utils/codec.js.map +1 -0
  63. package/dist/src/utils/debug.d.ts +10 -0
  64. package/dist/src/utils/debug.js +15 -0
  65. package/dist/src/utils/debug.js.map +1 -0
  66. package/dist/src/utils/hash.d.ts +40 -0
  67. package/dist/src/utils/hash.js +75 -0
  68. package/dist/src/utils/hash.js.map +1 -0
  69. package/dist/src/utils/http.d.ts +24 -0
  70. package/dist/src/utils/http.js +151 -0
  71. package/dist/src/utils/http.js.map +1 -0
  72. package/dist/src/utils/index.d.ts +6 -0
  73. package/dist/src/utils/index.js +10 -0
  74. package/dist/src/utils/index.js.map +1 -0
  75. package/dist/src/utils/io.d.ts +26 -0
  76. package/dist/src/utils/io.js +53 -0
  77. package/dist/src/utils/io.js.map +1 -0
  78. package/dist/src/utils/parse.d.ts +26 -0
  79. package/dist/src/utils/parse.js +51 -0
  80. package/dist/src/utils/parse.js.map +1 -0
  81. package/index.ts +26 -0
  82. package/openclaw.plugin.json +344 -0
  83. package/package.json +106 -0
  84. package/setup-entry.ts +12 -0
  85. package/skills/migpt-volume/SKILL.md +182 -0
  86. package/skills/migpt-volume/index.ts +50 -0
  87. package/src/channel.ts +519 -0
  88. package/src/config.ts +299 -0
  89. package/src/message.ts +186 -0
  90. package/src/mi/account.ts +184 -0
  91. package/src/mi/common.ts +105 -0
  92. package/src/mi/index.ts +4 -0
  93. package/src/mi/mina.ts +261 -0
  94. package/src/mi/miot.ts +193 -0
  95. package/src/mi/typing.ts +93 -0
  96. package/src/onboarding.ts +136 -0
  97. package/src/openclaw-plugin-sdk.d.ts +185 -0
  98. package/src/outbound.ts +137 -0
  99. package/src/runtime.ts +14 -0
  100. package/src/service.ts +246 -0
  101. package/src/speaker.ts +264 -0
  102. package/src/tts/mimo.ts +300 -0
  103. package/src/types.ts +34 -0
  104. package/src/utils/codec.ts +206 -0
  105. package/src/utils/debug.ts +16 -0
  106. package/src/utils/hash.ts +104 -0
  107. package/src/utils/http.ts +193 -0
  108. package/src/utils/index.ts +5 -0
  109. package/src/utils/io.ts +68 -0
  110. package/src/utils/parse.ts +64 -0
  111. package/tsconfig.json +25 -0
package/README.md ADDED
@@ -0,0 +1,690 @@
1
+ # migpt-claw
2
+
3
+ 小米小爱音箱 OpenClaw Channel 插件,让小爱音箱成为你的 🦞龙虾 语音助手。
4
+
5
+ ## 功能特性
6
+
7
+ - 🎤 **语音对话** - 对小爱音箱说话,🦞 语音回复
8
+ - 🔇 **抢答抑制** - 自动暂停小爱原生回复,避免与 AI 回复冲突
9
+ - 🔁 **持续对话** - 一次唤醒连续对话,无需重复说"小爱同学"
10
+ - 🎯 **智能分流** - 纯对话走 OpenClaw,音乐/硬件控制走小爱原生
11
+ - 🎛️ **硬件控制过滤** - 可配置的硬件控制指令动词,支持设备名+动词模式
12
+ - 🗣️ **MiMo TTS** - 支持小米 MiMo-V2.5-TT 自定义语音合成(流式)
13
+ - 📦 **流式输出** - 长文本分块播放,降低延迟
14
+ - 🔔 **状态提示** - 支持启动播报和收到消息提示音
15
+
16
+ ## 快速开始
17
+
18
+ ### 第一步:安装插件
19
+
20
+ #### 方式一:Git 克隆 + 本地安装(推荐)
21
+
22
+ 适用于远程服务器或网络受限环境:
23
+
24
+ ```bash
25
+ # 1. 克隆仓库到 OpenClaw 插件目录
26
+ git clone https://github.com/z-qinghui/migpt-claw.git ~/.openclaw/plugins/migpt-claw
27
+
28
+ # 2. 从本地路径安装(--link 模式,后续更新只需 git pull)
29
+ openclaw plugins install ~/.openclaw/plugins/migpt-claw --link
30
+ ```
31
+
32
+ #### 方式二:通过 Git 直接安装
33
+
34
+ 适用于本地机器且网络畅通:
35
+
36
+ ```bash
37
+ openclaw plugins install "git:github.com/z-qinghui/migpt-claw@main"
38
+ ```
39
+
40
+ #### 方式三:通过 npm 安装
41
+
42
+ ```bash
43
+ openclaw plugins install npm:@z-qinghui/migpt-claw
44
+ ```
45
+
46
+ #### 方式四:通过 ClawHub 插件市场安装
47
+
48
+ ```bash
49
+ openclaw plugins install clawhub:@z-qinghui/migpt-claw
50
+ ```
51
+
52
+ ### 第二步:配置账号
53
+
54
+ 编辑 `~/.openclaw/openclaw.json`,在 `channels` 中添加 migpt 配置:
55
+
56
+ ```json
57
+ {
58
+ "channels": {
59
+ "migpt": {
60
+ "enabled": true,
61
+ "userId": "你的小米ID",
62
+ "password": "你的密码",
63
+ "passToken": "你的passToken",
64
+ "devices": ["客厅音箱"],
65
+ "announceOnStart": true,
66
+ "startupMessage": "您的小龙虾已上线,随时为您服务",
67
+ "acknowledgeOnReceive": true,
68
+ "receiveMessage": "收到,处理中",
69
+ "speakerControl": "mina",
70
+ "streaming": true,
71
+ "keepAlive": true,
72
+ "keepAliveTimeout": 30,
73
+ "keepAliveEnterKeywords": ["打开连续对话", "进入持续对话", "开启持续对话", "持续对话模式"],
74
+ "keepAliveExitKeywords": ["关闭连续对话", "退出持续对话", "退出持续对话模式", "再见"],
75
+ "hardwareControlVerbs": [
76
+ "播放", "打开", "关闭", "暂停", "继续", "停止", "切换",
77
+ "开启", "关掉", "开", "关", "启动", "调节",
78
+ "调高", "调低", "调大", "调小", "调亮", "调暗", "增大", "减小", "设置", "调到",
79
+ "导航", "拨打", "打电话", "呼叫", "发短信", "发消息"
80
+ ],
81
+ "mimo": {
82
+ "apiKey": "你的MiMo API Key",
83
+ "baseUrl": "https://api.xiaomimimo.com/v1",
84
+ "model": "mimo-v2.5-tts",
85
+ "voice": "冰糖",
86
+ "style": "温柔活泼"
87
+ }
88
+ }
89
+ }
90
+ }
91
+ ```
92
+
93
+ **必填字段**:
94
+
95
+ | 字段 | 说明 | 获取方式 |
96
+ | --- | --- | --- |
97
+ | `userId` | 小米 ID(数字) | 小米账号「个人信息」-「小米 ID」 |
98
+ | `password` | 小米账号密码 | - |
99
+ | `passToken` | 登录辅助凭证(推荐) | 浏览器抓取小米登录 Cookie |
100
+ | `devices` | 音箱设备名称列表 | 米家 App 中的设备名称,**必须完全一致** |
101
+
102
+ **可选字段**:
103
+
104
+ | 字段 | 说明 | 默认值 |
105
+ | --- | --- | --- |
106
+ | `speakerControl` | 音箱控制方式 | `mina` |
107
+ | `announceOnStart` | 启动时播报上线文案 | `false` |
108
+ | `startupMessage` | 上线播报文案 | `您的小龙虾已上线,随时为您服务` |
109
+ | `acknowledgeOnReceive` | 收到消息时回复提示 | `false` |
110
+ | `receiveMessage` | 收到消息回复文案 | `收到,处理中` |
111
+ | `keepAlive` | 默认开启持续对话 | `false` |
112
+ | `keepAliveTimeout` | 持续对话超时秒数 | `30` |
113
+ | `keepAliveEnterKeywords` | 进入持续对话关键词 | `["打开连续对话", "进入持续对话", "开启持续对话", "持续对话模式"]` |
114
+ | `keepAliveExitKeywords` | 退出持续对话关键词 | `["关闭连续对话", "退出持续对话", "退出持续对话模式", "再见"]` |
115
+ | `hardwareControlVerbs` | 硬件控制指令动词关键词 | 25 个默认动词(见智能分流章节) |
116
+ | `streaming` | 启用流式 TTS 输出 | `true` |
117
+ | `systemPrompt` | 系统提示词,定制 AI 在音箱场景下的行为规范 | - |
118
+ | `mimo` | MiMo TTS 配置 | 不配置则使用小米原生 TTS |
119
+
120
+ ### 第三步:启动服务
121
+
122
+ ```bash
123
+ openclaw gateway restart
124
+ ```
125
+
126
+ ### 第四步:验证
127
+
128
+ ```bash
129
+ # 查看插件状态
130
+ openclaw plugins list --enabled --verbose
131
+
132
+ # 查看网关运行状态
133
+ openclaw gateway status --deep
134
+
135
+ # 如有问题,运行诊断
136
+ openclaw doctor
137
+ ```
138
+
139
+ ### 更新插件
140
+
141
+ ```bash
142
+ # 方式一:Git 安装的插件(--link 模式)
143
+ cd ~/.openclaw/plugins/migpt-claw && git pull
144
+ openclaw gateway restart
145
+
146
+ # 方式二:npm/ClawHub 安装的插件
147
+ openclaw plugins update migpt-claw
148
+ openclaw gateway restart
149
+ ```
150
+
151
+ ### 音箱控制方式
152
+
153
+ `speakerControl` 指定与小爱音箱通信的控制方式:
154
+
155
+ - **`mina`**(默认):使用 MiNA API,适用于大多数型号
156
+ - **`miot`**:使用 MIoT API,适用于部分特殊型号
157
+
158
+ **已知需要 `miot` 的型号**:LX04(小爱音箱 Pro)、X10A(小爱音箱 X10)、L05B/L05C(小爱音箱 Play 增强版)
159
+
160
+ 如果默认 `mina` 无法正常工作,请尝试切换为 `miot`。完整兼容性参考 [MiGPT 兼容性文档](https://github.com/idootop/mi-gpt/blob/main/docs/compatibility.md)。
161
+
162
+ ### 持续对话
163
+
164
+ 启用 `keepAlive` 后,一次唤醒可连续对话,无需重复说"小爱同学":
165
+
166
+ ```json
167
+ {
168
+ "channels": {
169
+ "migpt": {
170
+ "keepAlive": true,
171
+ "keepAliveTimeout": 30,
172
+ "keepAliveEnterKeywords": ["打开持续对话", "进入持续对话", "开启持续对话", "打开连续对话", "进入连续对话", "开启连续对话", "持续对话模式", "连续对话模式"],
173
+ "keepAliveExitKeywords": ["退出持续对话", "退出连续对话", "关闭持续对话", "关闭连续对话", "退出持续对话模式", "退出连续对话模式", "关闭持续对话模式", "关闭连续对话模式", "再见"]
174
+ }
175
+ }
176
+ }
177
+ ```
178
+
179
+ **使用方法**:
180
+
181
+ 1. 先正常唤醒小爱:"小爱同学"
182
+ 2. 说进入关键词:"打开连续对话" 或 "开启持续对话"
183
+ 3. 听到"已进入持续对话模式"提示后,即可连续对话
184
+ 4. 说退出关键词或等待超时自动退出
185
+
186
+ **默认关键词**:
187
+
188
+ | 功能 | 默认关键词 |
189
+ | --- | --- |
190
+ | 进入持续对话 | "打开持续对话"、"进入持续对话"、"开启持续对话"、"打开连续对话"、"进入连续对话"、"开启连续对话"、"持续对话模式"、"连续对话模式" |
191
+ | 退出持续对话 | "退出持续对话"、"退出连续对话"、"关闭持续对话"、"关闭连续对话"、"退出持续对话模式"、"退出连续对话模式"、"关闭持续对话模式"、"关闭连续对话模式"、"再见" |
192
+
193
+ **工作原理**:
194
+
195
+ - AI 回复后自动调用 MIoT 唤醒命令(`siid=5, aiid=3`)重新激活音箱麦克风
196
+ - 超时无新消息自动退出持续对话模式
197
+ - 支持语音关键词动态切换
198
+
199
+ **⚠️ 已知问题:小爱原生抢答**
200
+
201
+ 在持续对话模式下,小爱音箱听到你说话后会**先用原生 AI 回复**,然后 migpt-claw 才收到消息并用 OpenClaw 回复。这是 MiGPT 项目的已知限制([相关 issue](https://github.com/idootop/mi-gpt/issues/14)),目前没有完美解决方案。
202
+
203
+ **应对方法**:
204
+ - 等小爱原生回复说完后,OpenClaw 的回复会接着播放
205
+ - 或者说"小爱同学,闭嘴"打断原生回复
206
+
207
+ **抢答抑制**:收到新消息时立即暂停小爱原生回复,避免与 AI 回复冲突(借鉴 [MiGPT](https://github.com/idootop/mi-gpt) 的 `pause()` 机制)。
208
+
209
+ ### MiMo 自定义 TTS
210
+
211
+ 支持小米 [MiMo-V2.5-TT](https://mimo.mi.com/docs/zh-CN/quick-start/usage-guide/multimodal-understanding/speech-synthesis-v2.5) 语音合成,提供更自然的语音播报。
212
+
213
+ #### 基础配置
214
+
215
+ ```json
216
+ {
217
+ "channels": {
218
+ "migpt": {
219
+ "mimo": {
220
+ "apiKey": "your-mimo-api-key",
221
+ "baseUrl": "https://api.xiaomimimo.com/v1",
222
+ "model": "mimo-v2.5-tts",
223
+ "voice": "冰糖",
224
+ "style": "温柔活泼"
225
+ }
226
+ }
227
+ }
228
+ }
229
+ ```
230
+
231
+ #### 配置说明
232
+
233
+ | 字段 | 说明 | 默认值 |
234
+ | --- | --- | --- |
235
+ | `apiKey` | MiMo API Key(必填) | - |
236
+ | `baseUrl` | MiMo API 地址 | `https://api.xiaomimimo.com/v1` |
237
+ | `model` | TTS 模型 | `mimo-v2.5-tts` |
238
+ | `voice` | 预设音色 ID | `mimo_default` |
239
+ | `style` | 风格指令 | - |
240
+ | `stream` | 启用流式传输(降低首字延迟) | `true` |
241
+ | `port` | TTS 服务器固定端口(0 = 随机) | `0` |
242
+ | `host` | TTS 服务器监听地址 | `0.0.0.0` |
243
+
244
+ #### 可用音色
245
+
246
+ | 音色 | ID | 语言 | 性别 |
247
+ | --- | --- | --- | --- |
248
+ | 冰糖 | `冰糖` | 中文 | 女 |
249
+ | 茉莉 | `茉莉` | 中文 | 女 |
250
+ | 苏打 | `苏打` | 中文 | 男 |
251
+ | 白桦 | `白桦` | 中文 | 男 |
252
+ | Mia | `Mia` | 英文 | 女 |
253
+ | Chloe | `Chloe` | 英文 | 女 |
254
+
255
+ **风格示例**:`温柔`、`活泼`、`磁性`、`甜美`、`深沉`、`俏皮`、`东北话`、`四川话`
256
+
257
+ #### 工作原理
258
+
259
+ ```
260
+ 用户说话 → 小爱音箱 → MiMo TTS API(生成音频)→ 本地 HTTP 服务器托管 → 音箱播放
261
+ ```
262
+
263
+ 流式模式下,MiMo API 返回 PCM16 音频流,本地实时拼接为 WAV,边生成边播放,首字延迟更低。
264
+
265
+ #### ⚠️ 云服务器部署注意事项
266
+
267
+ **核心问题**:小爱音箱在你的**本地网络**,OpenClaw 在**云服务器**。音箱必须能访问 TTS 音频 URL。
268
+
269
+ **解决方案**:设置环境变量 `MIMO_TTS_HOST_IP` 为云服务器的**公网 IP**,并开放 TTS 端口。
270
+
271
+ **步骤**:
272
+
273
+ 1. **设置公网 IP 环境变量**
274
+
275
+ 在 `docker-compose.yml` 中添加:
276
+ ```yaml
277
+ environment:
278
+ - MIMO_TTS_HOST_IP=你的公网IP
279
+ ```
280
+
281
+ 2. **配置固定端口**
282
+
283
+ 在 `openclaw.json` 的 mimo 配置中添加固定端口(避免每次重启端口变化):
284
+ ```json
285
+ "mimo": {
286
+ "apiKey": "...",
287
+ "port": 18790
288
+ }
289
+ ```
290
+
291
+ 3. **开放防火墙和安全组**
292
+
293
+ - 服务器防火墙:`iptables -A INPUT -p tcp --dport 18790 -j ACCEPT`
294
+ - 云服务商安全组:在控制台添加入方向规则,放行 TCP 端口 18790
295
+
296
+ 4. **重启服务**
297
+
298
+ ```bash
299
+ docker compose up -d
300
+ ```
301
+
302
+ #### 本地网络部署
303
+
304
+ 如果 OpenClaw 和小爱音箱在**同一局域网**,无需设置 `MIMO_TTS_HOST_IP`,插件会自动检测局域网 IP。
305
+
306
+ #### 故障排查
307
+
308
+ **问题 1:音箱亮灯但没声音**
309
+
310
+ 原因:音箱无法访问 TTS 音频 URL。
311
+
312
+ 排查步骤:
313
+ ```bash
314
+ # 1. 查看 TTS 服务器日志,确认 URL
315
+ docker logs openclaw 2>&1 | grep "MiMo TTS 播放"
316
+ # 输出示例: 🔊 MiMo TTS 播放: http://47.103.150.141:18790/audio/xxx.wav
317
+
318
+ # 2. 测试 URL 是否可访问
319
+ curl -I http://47.103.150.141:18790/audio/xxx.wav
320
+ # 应返回 HTTP 200
321
+
322
+ # 3. 如果返回超时/拒绝连接,检查:
323
+ # - 防火墙是否放行端口
324
+ # - 云服务商安全组是否放行
325
+ # - MIMO_TTS_HOST_IP 是否正确
326
+ ```
327
+
328
+ **问题 2:TTS 端口与 OpenClaw 冲突**
329
+
330
+ 错误日志:`EADDRINUSE: address already in use`
331
+
332
+ 原因:mimo.port 设置的端口被其他服务占用。
333
+
334
+ 解决:更换端口,确保不与 OpenClaw(默认 37105)冲突。
335
+
336
+ **问题 3:MiMo API 调用失败**
337
+
338
+ 错误日志:`⚠️ MiMo TTS 失败,回退到原生 TTS`
339
+
340
+ 排查步骤:
341
+ ```bash
342
+ # 1. 检查 API Key 是否正确
343
+ docker logs openclaw 2>&1 | grep "MiMo API error"
344
+
345
+ # 2. 测试 API 连通性
346
+ curl -X POST https://api.xiaomimimo.com/v1/chat/completions \
347
+ -H "api-key: your-api-key" \
348
+ -H "Content-Type: application/json" \
349
+ -d '{"model":"mimo-v2.5-tts","messages":[{"role":"assistant","content":"测试"}],"audio":{"format":"wav","voice":"冰糖"}}'
350
+
351
+ # 3. 检查 baseUrl 是否正确(有些 API 代理地址不同)
352
+ ```
353
+
354
+ **问题 4:查看详细日志**
355
+
356
+ ```bash
357
+ # 查看 MiMo TTS 相关日志
358
+ docker logs openclaw 2>&1 | grep -i "mimo\|tts"
359
+
360
+ # 查看完整启动日志
361
+ docker logs openclaw --tail 200
362
+ ```
363
+
364
+ ### 智能分流
365
+
366
+ 插件自动区分对话和硬件控制命令:
367
+
368
+ - **纯对话**(小爱回复类型为 TTS/LLM 且仅有 1 条回答)→ 发送给 OpenClaw AI 处理
369
+ - **音乐播放**(小爱回复包含 TTS + Audio 多条回答)→ 由小爱原生处理
370
+ - **硬件控制**(开关灯、调节亮度、风扇/空调/加湿器等)→ 由小爱原生处理
371
+
372
+ #### 硬件控制指令过滤
373
+
374
+ 插件通过匹配用户语音中的**动词关键词**来识别硬件控制指令,匹配到的指令将跳过 AI 处理,由小爱原生处理。
375
+
376
+ **支持的模式**:
377
+ - **直接模式**:动词 + 内容(如"打开灯"、"播放音乐")
378
+ - **设备+动词模式**:设备名 + 动词 + 内容(如"大白调小一些"、"吸顶灯调亮一些")
379
+
380
+ **默认动词列表**(25 个):
381
+ ```
382
+ 播放、打开、关闭、暂停、继续、停止、切换、开启、关掉、开、关、启动、调节
383
+ 调高、调低、调大、调小、调亮、调暗、增大、减小、设置、调到
384
+ 导航、拨打、打电话、呼叫、发短信、发消息
385
+ ```
386
+
387
+ **自定义配置**:
388
+
389
+ 在 `openclaw.json` 的 `channels.migpt` 中添加 `hardwareControlVerbs` 字段:
390
+
391
+ ```json
392
+ {
393
+ "channels": {
394
+ "migpt": {
395
+ "hardwareControlVerbs": [
396
+ "播放", "打开", "关闭", "暂停", "调高", "调低",
397
+ "调亮", "调暗", "你的自定义动词..."
398
+ ]
399
+ }
400
+ }
401
+ }
402
+ ```
403
+
404
+ **过滤逻辑**:
405
+ 1. 豁免持续对话控制指令(进入/退出关键词)
406
+ 2. 匹配硬件控制动词关键词
407
+ 3. 匹配成功 → 跳过 AI,由小爱原生处理
408
+ 4. 匹配失败 → 发送给 OpenClaw AI 处理
409
+
410
+ **注意事项**:
411
+ - 动词列表应保持精简,避免正常对话被误过滤
412
+ - 移除了系统控制类动词(重启、关机、查询等)以减少误判
413
+ - 配置变更后需要重启 OpenClaw 容器生效
414
+
415
+ ## 设备名称
416
+
417
+ 设备名称必须与米家 App 中设置的名称**完全一致**(包括大小写和空格)。
418
+
419
+ 如果不确定设备名称,可以:
420
+
421
+ 1. 启动服务查看日志中的设备列表
422
+ 2. 日志中会打印所有可用设备
423
+ 3. 使用 `docker logs openclaw 2>&1 | grep -i "设备\|device"` 查看
424
+
425
+ ## 使用技能
426
+
427
+ ### 播报规范
428
+
429
+ 插件内置智能播报规范,AI 会自动判断内容是否适合语音播报:
430
+
431
+ - ✅ **适合播报**:简短回复、确认信息、简单问答
432
+ - ❌ **不适合播报**:代码、长文、数据、多媒体内容
433
+
434
+ 对于不适合播报的内容,AI 会告知用户已通过其他渠道(如微信、邮件等)发送。
435
+
436
+ ### 音量控制
437
+
438
+ 插件注册了 `set_volume` 和 `get_volume` 工具,AI 可通过 tool call 控制音箱音量:
439
+
440
+ - "把音量调到 50"
441
+ - "现在音量多大?"
442
+
443
+ ## 故障排查
444
+
445
+ ### 配置验证失败
446
+
447
+ **错误**: `invalid config: must not have additional properties: "hardwareControlVerbs"`
448
+
449
+ **原因**: OpenClaw 运行时缓存了插件 schema,需要重启服务才能加载新配置
450
+
451
+ **解决**:
452
+ ```bash
453
+ # 重启 OpenClaw 容器
454
+ docker restart openclaw
455
+
456
+ # 验证配置是否生效
457
+ docker logs openclaw --tail 10 | grep -i "invalid config"
458
+ ```
459
+
460
+ **排查顺序**(必须遵守):
461
+ 1. **看日志** → `docker logs openclaw 2>&1 | grep -i error`
462
+ 2. **确认重启** → 服务是否重启/重载?
463
+ 3. **检查运行时** → 内存中的配置(而非磁盘文件)
464
+ 4. **最后检查文件** → 文件内容是否正确
465
+
466
+ ### 登录失败
467
+
468
+ **错误**: `❌ 本次登录需要验证码,请使用 passToken 重新登录`
469
+
470
+ **解决**: 使用 passToken 替代密码登录,或尝试多次登录直到不需要验证码
471
+
472
+ ### 设备未找到
473
+
474
+ **错误**: `❌ 找不到设备:客厅音箱`
475
+
476
+ **解决**:
477
+
478
+ 1. 检查设备名称是否与米家 App 中完全一致
479
+ 2. 查看启动日志中的可用设备列表:`docker logs openclaw 2>&1 | grep -i "设备\|device"`
480
+ 3. 注意错别字,如「音响」vs「音箱」
481
+
482
+ ### 消息轮询失败
483
+
484
+ **错误**: `❌ getConversations failed`
485
+
486
+ **解决**:
487
+
488
+ 1. 检查网络连接
489
+ 2. 检查 serviceToken 是否过期
490
+ 3. 删除 `.mi.json` 缓存文件重新登录
491
+
492
+ ## 项目结构
493
+
494
+ ```text
495
+ migpt-claw/
496
+ ├── index.ts # 插件完整入口
497
+ ├── setup-entry.ts # 轻量级 Setup 入口(onboarding/config repair)
498
+ ├── openclaw.plugin.json # 插件清单(marketplace 发现+配置 schema)
499
+ ├── src/
500
+ │ ├── channel.ts # Channel 核心(消息处理、智能分流、持续对话)
501
+ │ ├── service.ts # 认证服务(MiNA/MIoT 统一接口)
502
+ │ ├── message.ts # 消息轮询
503
+ │ ├── speaker.ts # TTS 播放(支持 MiMo + 原生)
504
+ │ ├── config.ts # 配置解析
505
+ │ ├── types.ts # 类型定义
506
+ │ ├── outbound.ts # 消息发送
507
+ │ ├── onboarding.ts # 安装向导
508
+ │ ├── runtime.ts # 运行时管理
509
+ │ ├── openclaw-plugin-sdk.d.ts # OpenClaw SDK 类型定义
510
+ │ ├── tts/ # 自定义 TTS
511
+ │ │ └── mimo.ts # MiMo-V2.5-TT 语音合成
512
+ │ ├── mi/ # 小米服务
513
+ │ │ ├── index.ts # 服务导出
514
+ │ │ ├── mina.ts # MiNA API
515
+ │ │ ├── miot.ts # MIoT API
516
+ │ │ ├── account.ts # 账号认证
517
+ │ │ ├── common.ts # 通用工具
518
+ │ │ └── typing.ts # 类型定义
519
+ │ └── utils/ # 工具函数
520
+ │ ├── index.ts # 工具导出
521
+ │ ├── http.ts # HTTP 请求
522
+ │ ├── codec.ts # 编解码
523
+ │ ├── hash.ts # 哈希工具
524
+ │ ├── io.ts # 文件 IO
525
+ │ ├── debug.ts # 调试工具
526
+ │ └── parse.ts # 解析工具
527
+ └── skills/
528
+ └── migpt-volume/ # 音量控制技能
529
+ ├── index.ts
530
+ └── SKILL.md
531
+ ```
532
+
533
+ ## 更新日志
534
+
535
+ ### 2026-06-21
536
+
537
+ **新增**:
538
+ - ✨ **硬件控制指令可配置**:新增 `hardwareControlVerbs` 配置项,允许用户自定义硬件控制指令动词关键词列表
539
+ - ✨ **智能分流增强**:支持"设备名+动词+内容"模式(如"大白调小一些"、"吸顶灯调亮一些")
540
+
541
+ **修复**:
542
+ - 🐛 **Schema 验证问题**:修复 `hardwareControlVerbs` 字段添加到 `channelConfigs` 后的配置验证失败,需要重启 OpenClaw 容器加载新 schema
543
+ - 🐛 **退出持续对话检测**:优化退出关键词检测逻辑,支持 AI 回复中包含退出关键词时自动退出
544
+
545
+ **优化**:
546
+ - ⚡ **持续对话关键词**:扩展进入/退出关键词支持更多变体(打开/进入/开启 + 持续/连续对话/模式)
547
+ - ⚡ **硬件控制动词精简**:移除系统控制类动词(重启、关机、查询等),避免正常对话被误过滤
548
+
549
+ **配置变更**:
550
+ - 新增 `hardwareControlVerbs` 配置项(默认 25 个动词)
551
+ - 配置位置:`channels.migpt.hardwareControlVerbs`
552
+
553
+ ```json
554
+ {
555
+ "channels": {
556
+ "migpt": {
557
+ "hardwareControlVerbs": [
558
+ "播放", "打开", "关闭", "暂停", "继续", "停止", "切换",
559
+ "开启", "关掉", "开", "关", "启动", "调节",
560
+ "调高", "调低", "调大", "调小", "调亮", "调暗", "增大", "减小", "设置", "调到",
561
+ "导航", "拨打", "打电话", "呼叫", "发短信", "发消息"
562
+ ]
563
+ }
564
+ }
565
+ }
566
+ ```
567
+
568
+ ### 2026-06-15
569
+
570
+ **修复**:
571
+ - 🐛 **持续对话音频播放完成问题**:之前唤醒音箱时会打断正在播放的回复,现在根据音频实际时长等待播放完成后再唤醒(额外加 0.5s 缓冲)
572
+ - 🐛 **channelConfigs 配置警告**:修复 `channel plugin manifest declares migpt without channelConfigs metadata` 警告,使用正确的 `schema` 包装格式
573
+ - 🐛 **新增 enabled/streaming 配置项**:在 channelConfigs schema 中添加 `enabled` 和 `streaming` 属性定义
574
+
575
+ **优化**:
576
+ - ✨ **音频时长返回**:MiMo TTS `synthesize()` 现在返回 `duration`(音频时长),用于精确控制唤醒时机
577
+ - ✨ **调试日志增强**:`Speaker.play()` 和 `MiNA.play()` 添加详细日志输出,便于问题排查
578
+
579
+ ## 开发
580
+
581
+ ```bash
582
+ # 安装依赖
583
+ npm install
584
+
585
+ # 开发模式(监听文件变化自动构建)
586
+ npm run dev
587
+
588
+ # 构建
589
+ npm run build
590
+
591
+ # 本地测试安装
592
+ openclaw plugins install . --link
593
+ openclaw gateway restart
594
+ ```
595
+
596
+ ### 发布到 npm
597
+
598
+ 前置条件:拥有 `@z-qinghui` 组织的 npm 发布权限。
599
+
600
+ ```bash
601
+ # 1. 构建
602
+ npm run build
603
+
604
+ # 2. 登录 npm(如未登录)
605
+ npm login
606
+
607
+ # 3. 发布(scoped 包自动使用 public 访问权限)
608
+ npm publish
609
+
610
+ # 4. 验证
611
+ npm view @z-qinghui/migpt-claw
612
+ ```
613
+
614
+ 发布后,用户即可通过 `openclaw plugins install npm:@z-qinghui/migpt-claw` 安装。
615
+
616
+ ### 注册到 ClawHub
617
+
618
+ ClawHub 插件市场会自动索引 npm 上的 OpenClaw 插件。npm 发布完成后:
619
+
620
+ 1. 确保 `openclaw.plugin.json` 中的 `version` 与 npm 包版本一致
621
+ 2. ClawHub 会自动检测到新版本(通常需要几分钟同步)
622
+ 3. 用户即可通过 `openclaw plugins install clawhub:@z-qinghui/migpt-claw` 安装
623
+
624
+ > 如 ClawHub 未自动索引,可在 OpenClaw 社区提交插件注册申请。
625
+ > 插件市场发现依赖 `package.json` 中的 `openclaw` 元数据和 `openclaw.plugin.json` 插件清单,这两项均已配置完成。
626
+
627
+ ## 相关项目
628
+
629
+ 本项目受到以下优秀项目的启发和帮助:
630
+
631
+ - **[MiGPT](https://github.com/idootop/mi-gpt)** - 小爱音箱接入 ChatGPT/豆包的独立应用(已归档),支持长短期记忆、角色扮演、自定义 TTS、智能家居 Agent 等功能。本项目借鉴了其小米 API 对接方案
632
+ - **[MiGPT Next](https://github.com/idootop/migpt-next)** - MiGPT 的继任版本,让小爱音箱接入 AI 大模型
633
+ - **[MiService](https://github.com/yihong0618/MiService)** - 小米账号认证和米家设备控制基础库
634
+ - **[Open-XiaoAI](https://github.com/idootop/open-xiaoai)** - MiGPT 作者推荐的小爱音箱 Pro 继任项目,支持自定义唤醒词、连续对话
635
+
636
+ ### MiGPT vs migpt-claw 对比
637
+
638
+ | 维度 | MiGPT | migpt-claw |
639
+ | --- | --- | --- |
640
+ | 架构 | 独立应用(Docker/Node.js) | OpenClaw Channel 插件 |
641
+ | AI 接入 | 直接调用 ChatGPT/豆包 API | 通过 OpenClaw 网关,支持任意模型 |
642
+ | 记忆系统 | 内置长短期记忆 | 依赖 OpenClaw 管理 |
643
+ | 部署方式 | Docker 容器 / npm 包 | 插件市场安装(ClawHub/npm/Git) |
644
+ | 扩展能力 | 自成体系 | Skills 系统 + 多渠道协作(如音箱+微信) |
645
+ | TTS 定制 | 支持豆包语音音色 | 支持 MiMo-V2.5-TT + 小米原生 TTS |
646
+ | 配置方式 | `.env` + `.migpt.js` | OpenClaw 统一配置 |
647
+ | 项目状态 | 已归档(2026.04) | 活跃维护 |
648
+
649
+ 向以上项目的作者致敬!🙏
650
+
651
+ ## 开源协议
652
+
653
+ MIT License
654
+
655
+ Copyright (c) 2024
656
+
657
+ Permission is hereby granted, free of charge, to any person obtaining a copy
658
+ of this software and associated documentation files (the "Software"), to deal
659
+ in the Software without restriction, including without limitation the rights
660
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
661
+ copies of the Software, and to permit persons to whom the Software is
662
+ furnished to do so, subject to the following conditions:
663
+
664
+ The above copyright notice and this permission notice shall be included in all
665
+ copies or substantial portions of the Software.
666
+
667
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
668
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
669
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
670
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
671
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
672
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
673
+ SOFTWARE.
674
+
675
+ ## 免责声明
676
+
677
+ 本项目仅供学习和研究使用,不得用于任何商业用途或非法目的。
678
+
679
+ - 使用本项目时,请遵守当地法律法规和小米公司的相关服务条款
680
+ - 本项目与小米公司无任何关联,不构成任何官方支持或背书
681
+ - 使用本项目可能导致小米账号异常,请谨慎使用并自行承担风险
682
+ - 建议仅使用测试账号或非主要账号进行体验
683
+ - 如因使用本项目造成的任何损失(包括但不限于账号封禁、数据丢失等),本项目作者不承担任何责任
684
+ - 本项目按「原样」提供,不提供任何明示或暗示的保证
685
+
686
+ 如将本项目用于生产环境或其他重要场景,请务必:
687
+
688
+ 1. 仔细阅读并遵守小米开放平台的相关规范
689
+ 2. 通过官方渠道获取合法的 API 调用权限
690
+ 3. 评估潜在的法律和技术风险