@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 +1 -1
- package/skills/yoyo-control/SKILL.md +18 -18
- package/skills/yoyo-control/references/alarm-create.md +10 -10
- package/skills/yoyo-control/references/app-close.md +85 -0
- package/skills/yoyo-control/references/app-open.md +90 -2
- package/skills/yoyo-control/references/call-phone.md +1 -1
- package/skills/yoyo-control/references/hotspot.md +1 -1
- package/skills/yoyo-control/references/message-send.md +1 -1
- package/skills/yoyo-control/references/mobile-data.md +1 -1
- package/skills/yoyo-control/references/no-disturb.md +1 -1
- package/src/modules/claw-configs/provider.ts +164 -0
package/package.json
CHANGED
|
@@ -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`
|
|
29
|
-
| `IP` | String | 节点网络IP
|
|
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
|
-
####
|
|
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
|
-
####
|
|
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
|
-
####
|
|
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 &
|
|
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` |
|
|
91
|
-
| `app` | `references/app-close.md` |
|
|
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
|
|
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
|
-
|
|
|
160
|
-
|
|
|
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
|
-
####
|
|
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
|
-
####
|
|
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
|
|
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
|
-
####
|
|
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
|
-
####
|
|
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
|
-
####
|
|
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
|
-
```
|
|
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
|
-
```
|
|
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
|
-
```
|
|
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
|
-
```
|
|
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
|
-
```
|
|
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
|
-
```
|
|
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
|
-
```
|
|
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
|
-
```
|
|
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
|
-
```
|
|
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
|
-
```
|
|
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
|
+
---
|
|
@@ -60,7 +60,7 @@ hotspot
|
|
|
60
60
|
|
|
61
61
|
```json
|
|
62
62
|
{
|
|
63
|
-
"
|
|
63
|
+
"actionType": {
|
|
64
64
|
"type": "string",
|
|
65
65
|
"enum": ["设置", "查询", "打开", "关闭"],
|
|
66
66
|
"description": "个人热点相关操作的动作类型,用于明确本次指令的主要行为。当涉及调整个人热点名称、密码、共享方式或频段等配置时使用设置;当获取当前热点开启状态、配置信息或连接设备列表时使用查询;当要求启用个人热点功能时使用打开;当要求停用个人热点功能时使用关闭。"
|
|
@@ -67,7 +67,7 @@ mobile-data
|
|
|
67
67
|
|
|
68
68
|
```json
|
|
69
69
|
{
|
|
70
|
-
"
|
|
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
|
-
"
|
|
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
|
+
}
|