@honor-claw/yoyo 1.0.5 → 1.0.6

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@honor-claw/yoyo",
3
- "version": "1.0.5",
3
+ "version": "1.0.6",
4
4
  "description": "OpenClaw Honor Yoyo connection plugin",
5
5
  "keywords": [
6
6
  "ai",
@@ -25,13 +25,13 @@ metadata: { "openclaw": { "emoji": "📱", "always": true } }
25
25
  | Parameter | Type | Description | Example |
26
26
  | --------- | ------ | -------------------------------------------------------------------------------------- | ------------------------- |
27
27
  | `Node` | String | 设备名称,显示节点的友好标识名称 | `Honor Magic6 Pro` |
28
- | `ID` | String | 节点唯一标识符,用于命令调用时的 `--node` 参数(推荐使用) | `f5f8916028aa5` |
29
- | `IP` | String | 节点网络IP地址,也可用于命令调用时的 `--node` 参数 (强烈使用) | `192.168.1.100` |
28
+ | `ID` | String | 节点唯一标识符,用于命令调用时的 `--node` 参数 | `f5f8916028aa5` |
29
+ | `IP` | String | 节点网络IP地址,用于命令调用时的 `--node` 参数。**推荐优先使用IP**,相比ID更稳定可靠 | `192.168.1.100` |
30
30
  | `Detail` | String | 设备详细信息,可能包含设备型号、操作系统版本等信息 | `Magic6 Pro, Android 14` |
31
31
  | `Status` | String | 节点连接状态,值包括:`connected`(已连接)、`disconnected`(离线)、`unknown`(未知) | `connected` |
32
32
  | `Caps` | String | 节点能力列表,逗号分隔的能力标识,表示该设备支持的操作类型 | `app,call,message,volume` |
33
33
 
34
- #### Capability Matching Logic
34
+ #### 能力匹配逻辑
35
35
 
36
36
  Match device capabilities with user intent:
37
37
 
@@ -41,7 +41,7 @@ Match device capabilities with user intent:
41
41
  3. Filter nodes that support the required operation
42
42
  ```
43
43
 
44
- #### Selection Rules
44
+ #### 设备选择规则
45
45
 
46
46
  **Automatic Selection** (single best match):
47
47
 
@@ -60,7 +60,7 @@ Match device capabilities with user intent:
60
60
  - No capability match → Inform user: "No device supports [operation]. Available capabilities: [list]"
61
61
  - All nodes offline → Suggest: "Check device connectivity and try again"
62
62
 
63
- #### Pre-selection Checklist
63
+ #### 预选择检查清单
64
64
 
65
65
  - ✅ Filter only `status: "connected"` nodes
66
66
  - ✅ Never attempt to control offline devices
@@ -68,7 +68,7 @@ Match device capabilities with user intent:
68
68
  - ✅ If multiple nodes match, ask user to select OR control all if appropriate
69
69
  - ✅ If no suitable node found, clearly inform user with available options
70
70
 
71
- ## Step 2. Plan Tool and Extract Command & Paramters
71
+ ## Step 2. Plan Tool and Extract Command & Parameters
72
72
 
73
73
  **⚠️ MANDATORY: Consult tool reference before every operation**
74
74
 
@@ -87,10 +87,10 @@ Before executing any device control operation, you **MUST** consult the correspo
87
87
  | `ringing-mode` | `references/ringing-mode.md` | 响铃模式管理工具。提供对系统响铃模式的管理与控制能力,支持对响铃模式的开启与关闭、相关行为的设置以及当前状态的查询,并可结合指定应用对其在响铃模式下的表现进行管理。 |
88
88
  | `vibration-mode` | `references/vibration-mode.md` | 系统震动反馈管理与控制工具。提供对系统震动反馈功能的统一管理与控制能力,支持震动模式的设置、状态查询、打开与关闭,并可分别管理静音状态下震动、响铃状态下震动,以及在点击导航栏或设备解锁等交互场景中的震动反馈。 |
89
89
  | `capture-screenshot` | `references/capture-screenshot.md` | 截屏功能管理与触发工具。提供对截屏功能的管理与触发能力,支持将当前手机屏幕内容以图片的形式保存,包括普通截屏和滚动截屏等操作。 |
90
- | `app` | `references/app-open.md` | 应用打开工具。用于帮助用户关闭指定的 APP 应用,且不涉及任何具体 App 内部操作。 |
91
- | `app` | `references/app-close.md` | 应用关闭工具。用于帮助用户打开指定的 APP 应用,且不涉及任何具体 App 内部操作。 |
90
+ | `app` | `references/app-open.md` | 应用打开工具。用于帮助用户打开指定的 APP 应用,且不涉及任何具体 App 内部操作。 |
91
+ | `app` | `references/app-close.md` | 应用关闭工具。用于帮助用户关闭指定的 APP 应用,且不涉及任何具体 App 内部操作。 |
92
92
  | `contact` | `references/contact-search.md` | 联系人查找服务工具。提供按姓名、昵称、电话号码检索联系人的能力,支持区分自然人名与机构/黄页条目,可处理模糊匹配、多结果列表展示及序号选择场景。 |
93
- | `call` | `references/call-phone.md` | 智能电话拨打与管理工具。提供全面的电话呼叫功能,支持通过姓名、电话号码或黄页服务发起呼叫;支持指定拨号使用的SIM卡(移动/联通/电信/卡槽);具备重拨最后号码、回拨已接听来电、回拨未接听来电及通用回拨功能; |
93
+ | `call` | `references/call-phone.md` | 智能电话拨打与管理工具。提供全面的电话呼叫功能,支持通过姓名、电话号码或黄页服务发起呼叫;支持指定拨号使用的SIM卡(移动/联通/电信/卡槽);具备重拨最后号码、回拨已接听来电、回拨未接听来电及通用回拨功能。 |
94
94
  | `message` | `references/message-send.md` | 提供发送短信的服务。支持通过电话号码或联系人名称发送短信内容,可使用黄页发送短信至公共服务号码,以及发送名片信息给指定联系人。 |
95
95
  | `local-search` | `references/local-search.md` | 查询手机文档、笔记、日程、图库、yoyo记忆、钱包等 |
96
96
  | `alarm` | `references/alarm-create.md` | 闹钟创建工具。用于创建闹钟,当用户明确创建/定一个闹钟时,属于创建闹钟。 |
@@ -123,7 +123,7 @@ Execute the following steps **in strict order** for each operation to construct
123
123
  - Enum values must match documentation exactly (case-sensitive)
124
124
  - Numeric values must be within defined ranges
125
125
 
126
- ### Error Handling Protocolreference
126
+ ### Error Handling Protocol
127
127
 
128
128
  | Scenario | Required Action |
129
129
  | ------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
@@ -156,8 +156,8 @@ Execute the following steps **in strict order** for each operation to construct
156
156
  | ---- | ------------------- | ------------------------------------------------------ | ---------------------------------------------------- |
157
157
  | 1 | **Node Identifier** | Extract `IP` or `ID` column from `nodes status` output | ❌ STOP: "Cannot use node. Use ID from nodes status" |
158
158
  | 2 | **Tool Reference** | Read `references/<tool>.md` file completely | ❌ STOP: "Tool reference not found" |
159
- | 4 | **Command Name** | Extract `command` exactly from tool documentation | ❌ STOP: "Command mismatch. Check documentation" |
160
- | 3 | **Required Params** | Extract `params` from tool documentation | ❌ STOP: "Missing required field: [field]" |
159
+ | 3 | **Command Name** | Extract `command` exactly from tool documentation | ❌ STOP: "Command mismatch. Check documentation" |
160
+ | 4 | **Required Params** | Extract `params` from tool documentation | ❌ STOP: "Missing required field: [field]" |
161
161
 
162
162
  ### Platform Detection and Command Format
163
163
 
@@ -165,7 +165,7 @@ Execute the following steps **in strict order** for each operation to construct
165
165
 
166
166
  Before executing any command, you **MUST** detect the current platform and use the appropriate command format. Using the wrong format will cause command execution failures.
167
167
 
168
- #### Platform Detection Logic
168
+ #### 平台检测逻辑
169
169
 
170
170
  ```
171
171
  ┌─────────────────────────────────────────────────────────────┐
@@ -178,7 +178,7 @@ Before executing any command, you **MUST** detect the current platform and use t
178
178
  └─────────────────────────────────────────────────────────────┘
179
179
  ```
180
180
 
181
- #### Platform-Specific Command Formats
181
+ #### 平台特定命令格式
182
182
 
183
183
  | Platform | Shell Type | Quote Style | JSON Escaping Required | Example Command |
184
184
  | ----------- | ---------- | ------------------------------- | ---------------------- | -------------------------------------------------------------------------------------------- |
@@ -222,7 +222,7 @@ node {baseDir}/scripts/invoke.js --node 192.168.1.100 --command volume.operate -
222
222
 
223
223
  ```
224
224
  ┌─────────────────────────────────────────────────────────────┐
225
- │ RETRY FLOW (Max 2 attempts) │
225
+ │ RETRY FLOW (Max 3 attempts) │
226
226
  ├─────────────────────────────────────────────────────────────┤
227
227
  │ Attempt 1 → FAIL → Wait 1s → Attempt 2 → FAIL → Wait 1s │
228
228
  │ → Attempt 3 → FAIL → STOP & REPORT ERROR │
@@ -258,7 +258,7 @@ node {baseDir}/scripts/invoke.js --node 192.168.1.100 --command volume.operate -
258
258
 
259
259
  ### Response Templates
260
260
 
261
- #### Simple Success
261
+ #### 简单成功响应
262
262
 
263
263
  ```
264
264
  ✅ [Operation] completed on [Device]
@@ -266,7 +266,7 @@ node {baseDir}/scripts/invoke.js --node 192.168.1.100 --command volume.operate -
266
266
  Example: "Volume set to 50% on Honor Magic6 (was 30%)"
267
267
  ```
268
268
 
269
- #### Complex Success
269
+ #### 复杂成功响应
270
270
 
271
271
  ```
272
272
  ✅ [Operation] completed on [Device]
@@ -282,7 +282,7 @@ Example:
282
282
  - Visibility: Visible for 2 minutes"
283
283
  ```
284
284
 
285
- #### Failure with Guidance
285
+ #### 失败响应与指导
286
286
 
287
287
  ```
288
288
  ❌ [Operation] failed on [Device]
@@ -140,7 +140,7 @@ alarm.create
140
140
 
141
141
  **Windows (Cmd) 执行命令**:
142
142
 
143
- ```Cmd
143
+ ```bash
144
144
  openclaw nodes invoke <ID> --command alarm.create --params "{\"time\":\"T10:00:00\",\"realRepeatType\":0,\"daysOfWeek\":0,\"specialTimeMillis\":0,\"skipHoliday\":false}"
145
145
  ```
146
146
 
@@ -171,7 +171,7 @@ openclaw nodes invoke <ID> --command alarm.create --params '{"time":"T10:00:00",
171
171
 
172
172
  **Windows (Cmd) 执行命令**:
173
173
 
174
- ```Cmd
174
+ ```bash
175
175
  openclaw nodes invoke <ID> --command alarm.create --params "{\"title\":\"购物\",\"time\":\"T15:00:00\",\"realRepeatType\":0,\"daysOfWeek\":0,\"specialTimeMillis\":0,\"skipHoliday\":false}"
176
176
  ```
177
177
 
@@ -202,7 +202,7 @@ openclaw nodes invoke <ID> --command alarm.create --params '{"title":"购物","t
202
202
 
203
203
  **Windows (Cmd) 执行命令**:
204
204
 
205
- ```Cmd
205
+ ```bash
206
206
  openclaw nodes invoke <ID> --command alarm.create --params "{\"title\":\"起床\",\"time\":\"T07:00:00\",\"realRepeatType\":2,\"daysOfWeek\":0,\"specialTimeMillis\":0,\"skipHoliday\":false}"
207
207
  ```
208
208
 
@@ -232,7 +232,7 @@ openclaw nodes invoke <ID> --command alarm.create --params '{"title":"起床","t
232
232
 
233
233
  **Windows (Cmd) 执行命令**:
234
234
 
235
- ```Cmd
235
+ ```bash
236
236
  openclaw nodes invoke <ID> --command alarm.create --params "{\"time\":\"T08:00:00\",\"realRepeatType\":1,\"daysOfWeek\":0,\"specialTimeMillis\":0,\"skipHoliday\":false}"
237
237
  ```
238
238
 
@@ -264,7 +264,7 @@ openclaw nodes invoke <ID> --command alarm.create --params '{"time":"T08:00:00",
264
264
 
265
265
  **Windows (Cmd) 执行命令**:
266
266
 
267
- ```Cmd
267
+ ```bash
268
268
  openclaw nodes invoke <ID> --command alarm.create --params "{\"time\":\"T15:00:00\",\"realRepeatType\":3,\"daysOfWeek\":20,\"specialTimeMillis\":0,\"skipHoliday\":false}"
269
269
  ```
270
270
 
@@ -296,7 +296,7 @@ openclaw nodes invoke <ID> --command alarm.create --params '{"time":"T15:00:00",
296
296
 
297
297
  **Windows (Cmd) 执行命令**:
298
298
 
299
- ```Cmd
299
+ ```bash
300
300
  openclaw nodes invoke <ID> --command alarm.create --params "{\"time\":\"T08:00:00\",\"realRepeatType\":5,\"daysOfWeek\":0,\"specialTimeMillis\":1773964800000,\"skipHoliday\":false}"
301
301
  ```
302
302
 
@@ -359,7 +359,7 @@ openclaw nodes invoke <ID> --command alarm.create --params '{"time":"T09:00:00",
359
359
 
360
360
  **Windows (Cmd) 执行命令**:
361
361
 
362
- ```Cmd
362
+ ```bash
363
363
  openclaw nodes invoke <ID> --command alarm.create --params "{\"time\":\"T09:00:00\",\"realRepeatType\":9,\"daysOfWeek\":0,\"specialTimeMillis\":0,\"skipHoliday\":false,\"bigWeek\":true}"
364
364
  ```
365
365
 
@@ -390,7 +390,7 @@ openclaw nodes invoke <ID> --command alarm.create --params '{"time":"T09:00:00",
390
390
 
391
391
  **Windows (Cmd) 执行命令**:
392
392
 
393
- ```Cmd
393
+ ```bash
394
394
  openclaw nodes invoke <ID> --command alarm.create --params "{\"time\":\"T09:00:00\",\"realRepeatType\":9,\"daysOfWeek\":0,\"specialTimeMillis\":0,\"skipHoliday\":false,\"bigWeek\":false}"
395
395
  ```
396
396
 
@@ -422,7 +422,7 @@ openclaw nodes invoke <ID> --command alarm.create --params '{"time":"T09:00:00",
422
422
 
423
423
  **Windows (Cmd) 执行命令**:
424
424
 
425
- ```Cmd
425
+ ```bash
426
426
  openclaw nodes invoke <ID> --command alarm.create --params "{\"time\":\"T18:00:00\",\"realRepeatType\":4,\"daysOfWeek\":0,\"specialTimeMillis\":0,\"skipHoliday\":false}"
427
427
  ```
428
428
 
@@ -452,7 +452,7 @@ openclaw nodes invoke <ID> --command alarm.create --params '{"time":"T18:00:00",
452
452
 
453
453
  **Windows (Cmd) 执行命令**:
454
454
 
455
- ```Cmd
455
+ ```bash
456
456
  openclaw nodes invoke <ID> --command alarm.create --params "{\"time\":\"T08:30:00\",\"realRepeatType\":10,\"daysOfWeek\":0,\"specialTimeMillis\":0,\"skipHoliday\":false}"
457
457
  ```
458
458
 
@@ -177,7 +177,92 @@ openclaw nodes invoke --node <ID> --command app.close --params "{\"app\":\"淘
177
177
 
178
178
  ```bash
179
179
  openclaw nodes invoke --node <ID> --command app.close --params '{"app":"淘宝","pkgName":"com.taobao.taobao","appDescription":"购物"}'
180
+ ```
181
+
182
+ ---
183
+
184
+ ### 示例 3: 关闭所有应用
185
+
186
+ **用户输入**: "关闭所有应用"
187
+
188
+ **工具**: "app.close"
189
+
190
+ **JSON 参数**:
191
+
192
+ ```json
193
+ {
194
+ "app": "all"
195
+ }
196
+ ```
197
+
198
+ **Windows (Cmd) 执行命令**:
199
+
200
+ ```bash
201
+ openclaw nodes invoke --node <ID> --command app.close --params "{\"app\":\"all\"}"
202
+ ```
203
+
204
+ **Linux (Bash) 执行命令**:
205
+
206
+ ```bash
207
+ openclaw nodes invoke --node <ID> --command app.close --params '{"app":"all"}'
208
+ ```
209
+
210
+ ---
211
+
212
+ ### 示例 4: 通过包名关闭应用
213
+
214
+ **用户输入**: "帮我关掉 com.tencent.mm"
215
+
216
+ **工具**: "app.close"
217
+
218
+ **JSON 参数**:
219
+
220
+ ```json
221
+ {
222
+ "app": "微信",
223
+ "pkgName": "com.tencent.mm"
224
+ }
225
+ ```
226
+
227
+ **Windows (Cmd) 执行命令**:
228
+
229
+ ```bash
230
+ openclaw nodes invoke --node <ID> --command app.close --params "{\"app\":\"微信\",\"pkgName\":\"com.tencent.mm\"}"
231
+ ```
232
+
233
+ **Linux (Bash) 执行命令**:
234
+
235
+ ```bash
236
+ openclaw nodes invoke --node <ID> --command app.close --params '{"app":"微信","pkgName":"com.tencent.mm"}'
237
+ ```
238
+
239
+ ---
240
+
241
+ ### 示例 5: 口语化关闭应用
242
+
243
+ **用户输入**: "帮我把抖音关了"
180
244
 
245
+ **工具**: "app.close"
246
+
247
+ **JSON 参数**:
248
+
249
+ ```json
250
+ {
251
+ "app": "抖音短视频",
252
+ "pkgName": "com.ss.android.ugc.aweme"
253
+ }
254
+ ```
255
+
256
+ **Windows (Cmd) 执行命令**:
257
+
258
+ ```bash
259
+ openclaw nodes invoke --node <ID> --command app.close --params "{\"app\":\"抖音短视频\",\"pkgName\":\"com.ss.android.ugc.aweme\"}"
260
+ ```
261
+
262
+ **Linux (Bash) 执行命令**:
263
+
264
+ ```bash
265
+ openclaw nodes invoke --node <ID> --command app.close --params '{"app":"抖音短视频","pkgName":"com.ss.android.ugc.aweme"}'
181
266
  ```
182
267
 
183
268
  ---
@@ -118,7 +118,7 @@ app.open
118
118
 
119
119
  ## Query 示例及输出
120
120
 
121
- ### 示例1: 打开指定应用
121
+ ### 示例 1: 打开指定应用
122
122
 
123
123
  **用户输入**: "打开微信"
124
124
 
@@ -147,7 +147,7 @@ openclaw nodes invoke --node <ID> --command app.open --params '{"app":"微信",
147
147
 
148
148
  ---
149
149
 
150
- ### 示例2: 通过类型描述打开应用
150
+ ### 示例 2: 通过类型描述打开应用
151
151
 
152
152
  **用户输入**: "打开生活类软件"
153
153
 
@@ -176,3 +176,91 @@ openclaw nodes invoke --node <ID> --command app.open --params '{"app":"支付宝
176
176
  ```
177
177
 
178
178
  ---
179
+
180
+ ### 示例 3: 通过包名打开应用
181
+
182
+ **用户输入**: "帮我启动 com.tencent.mm"
183
+
184
+ **工具**: "app.open"
185
+
186
+ **JSON 参数**:
187
+
188
+ ```json
189
+ {
190
+ "app": "微信",
191
+ "pkgName": "com.tencent.mm"
192
+ }
193
+ ```
194
+
195
+ **Windows (Cmd) 执行命令**:
196
+
197
+ ```bash
198
+ openclaw nodes invoke --node <ID> --command app.open --params "{\"app\":\"微信\",\"pkgName\":\"com.tencent.mm\"}"
199
+ ```
200
+
201
+ **Linux (Bash) 执行命令**:
202
+
203
+ ```bash
204
+ openclaw nodes invoke --node <ID> --command app.open --params '{"app":"微信","pkgName":"com.tencent.mm"}'
205
+ ```
206
+
207
+ ---
208
+
209
+ ### 示例 4: 打开带序号的应用
210
+
211
+ **用户输入**: "打开第二个微信"
212
+
213
+ **工具**: "app.open"
214
+
215
+ **JSON 参数**:
216
+
217
+ ```json
218
+ {
219
+ "app": "微信",
220
+ "pkgName": "com.tencent.mm",
221
+ "sequence": "第二个"
222
+ }
223
+ ```
224
+
225
+ **Windows (Cmd) 执行命令**:
226
+
227
+ ```bash
228
+ openclaw nodes invoke --node <ID> --command app.open --params "{\"app\":\"微信\",\"pkgName\":\"com.tencent.mm\",\"sequence\":\"第二个\"}"
229
+ ```
230
+
231
+ **Linux (Bash) 执行命令**:
232
+
233
+ ```bash
234
+ openclaw nodes invoke --node <ID> --command app.open --params '{"app":"微信","pkgName":"com.tencent.mm","sequence":"第二个"}'
235
+ ```
236
+
237
+ ---
238
+
239
+ ### 示例 5: 口语化打开应用
240
+
241
+ **用户输入**: "帮我运行一下抖音"
242
+
243
+ **工具**: "app.open"
244
+
245
+ **JSON 参数**:
246
+
247
+ ```json
248
+ {
249
+ "app": "抖音短视频",
250
+ "pkgName": "com.ss.android.ugc.aweme"
251
+ }
252
+ ```
253
+
254
+ **Windows (Cmd) 执行命令**:
255
+
256
+ ```bash
257
+ openclaw nodes invoke --node <ID> --command app.open --params "{\"app\":\"抖音短视频\",\"pkgName\":\"com.ss.android.ugc.aweme\"}"
258
+ ```
259
+
260
+ **Linux (Bash) 执行命令**:
261
+
262
+ ```bash
263
+ openclaw nodes invoke --node <ID> --command app.open --params '{"app":"抖音短视频","pkgName":"com.ss.android.ugc.aweme"}'
264
+ ```
265
+
266
+ ---
@@ -1,5 +1,5 @@
1
1
  ---
2
- name: call
2
+ name: call.phone
3
3
  description: >
4
4
  智能电话拨打与管理工具。提供全面的电话呼叫功能,
5
5
  支持通过姓名、电话号码或黄页服务发起呼叫;
@@ -60,7 +60,7 @@ hotspot
60
60
 
61
61
  ```json
62
62
  {
63
- "action_type": {
63
+ "actionType": {
64
64
  "type": "string",
65
65
  "enum": ["设置", "查询", "打开", "关闭"],
66
66
  "description": "个人热点相关操作的动作类型,用于明确本次指令的主要行为。当涉及调整个人热点名称、密码、共享方式或频段等配置时使用设置;当获取当前热点开启状态、配置信息或连接设备列表时使用查询;当要求启用个人热点功能时使用打开;当要求停用个人热点功能时使用关闭。"
@@ -1,5 +1,5 @@
1
1
  ---
2
- name: message-send
2
+ name: message.send
3
3
  description: >
4
4
  提供发送短信的服务。支持通过电话号码或联系人名称发送短信内容,
5
5
  可使用黄页发送短信至公共服务号码,以及发送名片信息给指定联系人。
@@ -67,7 +67,7 @@ mobile-data
67
67
 
68
68
  ```json
69
69
  {
70
- "action_type": {
70
+ "actionType": {
71
71
  "type": "string",
72
72
  "enum": ["设置", "查询", "打开", "关闭", "切换"],
73
73
  "description": "移动数据相关操作的动作类型,用于明确本次指令的主要行为。当涉及调整移动数据或流量相关配置时使用设置;当获取流量使用情况、账单、状态等信息时使用查询;当要求启用蜂窝移动数据连接时使用打开;当要求停用蜂窝移动数据连接时使用关闭;当在多张流量卡或不同配置之间进行选择时使用切换。"
@@ -68,7 +68,7 @@ no-disturb
68
68
 
69
69
  ```json
70
70
  {
71
- "action_type": {
71
+ "actionType": {
72
72
  "type": "string",
73
73
  "enum": ["设置", "查询", "打开", "关闭"],
74
74
  "description": "免打扰相关操作的动作类型,用于明确本次指令的主要行为。当涉及调整免打扰规则、时间段或放行条件时使用设置;当获取当前免打扰是否启用及相关配置状态时使用查询;当要求启用免打扰模式以屏蔽来电和通知时使用打开;当要求退出或关闭免打扰模式以恢复正常提醒时使用关闭。"
@@ -1,4 +1,6 @@
1
1
  import type { OpenClawConfig } from "openclaw/plugin-sdk";
2
+ import fs from "node:fs";
3
+ import path from "node:path";
2
4
 
3
5
  /**
4
6
  * 检测需要改名的provider
@@ -11,6 +13,7 @@ export function detectProvidersToRename(config: OpenClawConfig): Record<string,
11
13
  }
12
14
 
13
15
  const providers = Object.keys(config.models.providers);
16
+
14
17
  for (const provider of providers) {
15
18
  const lowerProvider = provider.trim().toLowerCase();
16
19
  if (lowerProvider.includes("minimax")) {
@@ -57,6 +60,20 @@ export function updateProviderReferences(
57
60
  );
58
61
  }
59
62
 
63
+ // 3. 更新 auth.profiles 配置
64
+ if (updatedConfig.auth?.profiles) {
65
+ updatedConfig.auth = {
66
+ ...updatedConfig.auth,
67
+ profiles: updateAuthProfilesProviderReferences(
68
+ updatedConfig.auth.profiles,
69
+ renameMap
70
+ ),
71
+ };
72
+
73
+ // 更新 auth.profiles 文件
74
+ updateAuthProfilesFiles(renameMap);
75
+ }
76
+
60
77
  return updatedConfig;
61
78
  }
62
79
 
@@ -227,4 +244,151 @@ function updateStringModelReference(
227
244
  return modelString;
228
245
  }
229
246
 
247
+ /**
248
+ * 更新 auth.profiles 配置中的 provider 引用
249
+ */
250
+ function updateAuthProfilesProviderReferences(
251
+ profiles: Record<string, any>,
252
+ renameMap: Record<string, string>
253
+ ): Record<string, any> {
254
+ const updatedProfiles: Record<string, any> = {};
255
+
256
+ for (const [profileId, profileConfig] of Object.entries(profiles)) {
257
+ const updatedProfile = { ...profileConfig };
258
+ const provider = updatedProfile.provider;
259
+ const newProvider = renameMap[provider];
260
+ if (newProvider) {
261
+ updatedProfile.provider = newProvider;
262
+ }
263
+ updatedProfiles[profileId] = updatedProfile;
264
+ }
265
+
266
+ return updatedProfiles;
267
+ }
268
+
269
+ /**
270
+ * 解析用户主目录路径
271
+ */
272
+ function resolveHomePath(): string {
273
+ if (process.platform === "win32") {
274
+ return process.env.USERPROFILE || "";
275
+ }
276
+ return process.env.HOME || "";
277
+ }
230
278
 
279
+ /**
280
+ * 获取所有 auth-profiles.json 文件路径
281
+ */
282
+ function getAuthProfilesFilePaths(stateDir?: string): string[] {
283
+ const paths: string[] = [];
284
+ const homePath = resolveHomePath();
285
+ const baseDir = stateDir || path.join(homePath, ".openclaw");
286
+
287
+ // 默认路径: ~/.openclaw/agents/main/agent/auth-profiles.json
288
+ const defaultPath = path.join(baseDir, "agents", "main", "agent", "auth-profiles.json");
289
+ if (fs.existsSync(defaultPath)) {
290
+ paths.push(defaultPath);
291
+ }
292
+
293
+ // 扫描所有 agent 目录
294
+ const agentsDir = path.join(baseDir, "agents");
295
+ if (fs.existsSync(agentsDir)) {
296
+ const agentDirs = fs.readdirSync(agentsDir, { withFileTypes: true });
297
+ for (const agentDir of agentDirs) {
298
+ if (agentDir.isDirectory()) {
299
+ const agentAuthPath = path.join(agentsDir, agentDir.name, "agent", "auth-profiles.json");
300
+ if (fs.existsSync(agentAuthPath) && !paths.includes(agentAuthPath)) {
301
+ paths.push(agentAuthPath);
302
+ }
303
+ }
304
+ }
305
+ }
306
+
307
+ return paths;
308
+ }
309
+
310
+ /**
311
+ * 更新 auth-profiles.json 文件中的 provider 引用
312
+ */
313
+ export function updateAuthProfilesFiles(
314
+ renameMap: Record<string, string>,
315
+ stateDir?: string
316
+ ): { updated: boolean; files: string[]; errors: string[] } {
317
+ const filePaths = getAuthProfilesFilePaths(stateDir);
318
+ const updatedFiles: string[] = [];
319
+ const errors: string[] = [];
320
+ let hasUpdates = false;
321
+
322
+ for (const filePath of filePaths) {
323
+ try {
324
+ // 读取文件
325
+ const content = fs.readFileSync(filePath, "utf-8");
326
+ const store = JSON.parse(content);
327
+
328
+ if (!store.profiles || typeof store.profiles !== "object") {
329
+ continue;
330
+ }
331
+
332
+ let fileHasUpdates = false;
333
+
334
+ // 更新 profiles 中的 provider
335
+ for (const [profileId, credential] of Object.entries(store.profiles)) {
336
+ const cred = credential as any;
337
+ const provider = cred.provider;
338
+ const newProvider = renameMap[provider];
339
+ if (newProvider && provider !== newProvider) {
340
+ cred.provider = newProvider;
341
+ fileHasUpdates = true;
342
+ }
343
+ }
344
+
345
+ // 更新 order 中的 provider key
346
+ if (store.order && typeof store.order === "object") {
347
+ const newOrder: Record<string, string[]> = {};
348
+ for (const [provider, profileList] of Object.entries(store.order)) {
349
+ const newProvider = renameMap[provider];
350
+ const targetProvider = newProvider || provider;
351
+ newOrder[targetProvider] = profileList;
352
+ if (newProvider && provider !== newProvider) {
353
+ fileHasUpdates = true;
354
+ }
355
+ }
356
+ if (fileHasUpdates) {
357
+ store.order = newOrder;
358
+ }
359
+ }
360
+
361
+ // 更新 lastGood 中的 provider key
362
+ if (store.lastGood && typeof store.lastGood === "object") {
363
+ const newLastGood: Record<string, string> = {};
364
+ for (const [provider, profileId] of Object.entries(store.lastGood)) {
365
+ const newProvider = renameMap[provider];
366
+ const targetProvider = newProvider || provider;
367
+ newLastGood[targetProvider] = profileId;
368
+ if (newProvider && provider !== newProvider) {
369
+ fileHasUpdates = true;
370
+ }
371
+ }
372
+ if (fileHasUpdates) {
373
+ store.lastGood = newLastGood;
374
+ }
375
+ }
376
+
377
+ // 如果有更新,保存文件
378
+ if (fileHasUpdates) {
379
+ fs.writeFileSync(filePath, JSON.stringify(store, null, 2) + "\n", "utf-8");
380
+ updatedFiles.push(filePath);
381
+ hasUpdates = true;
382
+ }
383
+ } catch (error) {
384
+ const errorMsg = error instanceof Error ? error.message : String(error);
385
+ errors.push(`${filePath}: ${errorMsg}`);
386
+ }
387
+ }
388
+
389
+ return {
390
+ updated: hasUpdates,
391
+ files: updatedFiles,
392
+ errors,
393
+ };
394
+ }