agentremote-cli 1.0.0__py3-none-any.whl
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.
- agentremote_cli-1.0.0.dist-info/METADATA +7 -0
- agentremote_cli-1.0.0.dist-info/RECORD +25 -0
- agentremote_cli-1.0.0.dist-info/WHEEL +5 -0
- agentremote_cli-1.0.0.dist-info/entry_points.txt +2 -0
- agentremote_cli-1.0.0.dist-info/top_level.txt +1 -0
- remotecli/__init__.py +1 -0
- remotecli/agent.py +673 -0
- remotecli/agent_cache.py +274 -0
- remotecli/agent_modes.py +5 -0
- remotecli/agent_open.py +323 -0
- remotecli/agent_projection.py +308 -0
- remotecli/agent_result.py +81 -0
- remotecli/agent_utils.py +113 -0
- remotecli/agent_window.py +249 -0
- remotecli/cli.py +635 -0
- remotecli/client.py +120 -0
- remotecli/config/agentremote.cli.toml +6 -0
- remotecli/cua.py +213 -0
- remotecli/guides/GUIDE.md +397 -0
- remotecli/guides/agent.md +60 -0
- remotecli/guides/cua.md +60 -0
- remotecli/guides/rpa.md +45 -0
- remotecli/guides/shell.md +49 -0
- remotecli/rpa.py +57 -0
- remotecli/shell.py +71 -0
|
@@ -0,0 +1,397 @@
|
|
|
1
|
+
# remotecli 使用指南
|
|
2
|
+
|
|
3
|
+
`remotecli` 是 AgentRemote 的 Agent 侧 CLI。AI 沙箱通过它调用远程客户机能力:桌面控制、远程 Shell、预定义 RPA 流程。
|
|
4
|
+
|
|
5
|
+
这份文件是 `remotecli` 的主文档。旁边的 `agent.md`、`cua.md`、`shell.md`、`rpa.md` 只做速查入口,避免同一规则在多个文件里重复维护。
|
|
6
|
+
|
|
7
|
+
## 一句话架构
|
|
8
|
+
|
|
9
|
+
```text
|
|
10
|
+
AI / remotecli --HTTP--> Middleware --MQTT--> Runtime --插件--> 桌面 / Shell / RPA
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
AI 不直接接触 MQTT,也不直接连接客户机 Runtime。它只调用 `remotecli`,`remotecli` 只访问 Middleware HTTP API。
|
|
14
|
+
|
|
15
|
+
## 快速开始
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
python -m remotecli.cli \
|
|
19
|
+
--wait \
|
|
20
|
+
--middleware http://<MIDDLEWARE_IP>:9100 \
|
|
21
|
+
--tenant <TENANT_ID> \
|
|
22
|
+
--node <NODE_ID> \
|
|
23
|
+
--handle wch_v1_... \
|
|
24
|
+
shell info
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
常用全局参数:
|
|
28
|
+
|
|
29
|
+
| 参数 | 说明 |
|
|
30
|
+
|---|---|
|
|
31
|
+
| `--config` | CLI 配置文件,默认使用 `remotecli/config/agentremote.cli.toml` |
|
|
32
|
+
| `--middleware` | Middleware HTTP 地址 |
|
|
33
|
+
| `--tenant` | 租户 ID |
|
|
34
|
+
| `--node` | 目标客户机节点 ID |
|
|
35
|
+
| `--agent` | Agent ID,可选 |
|
|
36
|
+
| `--handle` | Auth Broker handle,格式通常为 `wch_v1_...` |
|
|
37
|
+
| `--wait` | 提交底层任务后轮询最终结果,必须放在 `cua` / `shell` / `rpa` 前 |
|
|
38
|
+
| `--wait-timeout` | 等待结果的最大秒数 |
|
|
39
|
+
| `--poll-interval` | 轮询间隔秒数 |
|
|
40
|
+
|
|
41
|
+
参数优先级遵循:命令行参数 > 环境变量 > TOML 配置 > 本地开发默认值。
|
|
42
|
+
|
|
43
|
+
## 先用哪个命令
|
|
44
|
+
|
|
45
|
+
普通 AI Agent 默认用 `agent` 子命令。只有需要底层能力时才降到 `cua`、`shell` 或 `rpa`。
|
|
46
|
+
|
|
47
|
+
| 目标 | 优先命令 | 何时降级 |
|
|
48
|
+
|---|---|---|
|
|
49
|
+
| 执行 PowerShell / cmd | `agent ps` / `agent cmd` | 需要异步提交或完整底层返回时用 `shell` |
|
|
50
|
+
| 打开或准备应用窗口 | `agent open <app>` | 要自定义启动脚本时用 `shell exec-script` |
|
|
51
|
+
| 判断页面是否 ready | `agent probe` | 已有 `pid/window_id` 时用 `cua probe-window` |
|
|
52
|
+
| 观察页面状态 | `agent observe` | 需要完整原始状态时加 `--format full` 或用 `cua get-window-state` |
|
|
53
|
+
| 点击 / 输入 / 热键 | `agent click/type/key/hotkey` | 坐标、右键、拖拽、多窗口手选时用 `cua` |
|
|
54
|
+
| 固定业务自动化流程 | `rpa run` | 不建议用 `agent` 拼固定 RPA 流程 |
|
|
55
|
+
| 查询异步结果 | `result <trace_id>` | `agent` 默认已自动等待,一般不需要 |
|
|
56
|
+
|
|
57
|
+
## Agent 高层入口
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
python -m remotecli.cli agent <action> [args]
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
`agent ...` 面向普通 AI 使用,默认会:
|
|
64
|
+
|
|
65
|
+
- 等待任务最终结果。
|
|
66
|
+
- 解包 Middleware 返回里的 `result.output` JSON 字符串。
|
|
67
|
+
- GUI 操作前按应用名自动执行 `list-apps -> list-windows`,拿到真实 `pid/window_id`。
|
|
68
|
+
- 使用同一个 `--session` 时缓存窗口引用,后续步骤复用,失败时自动刷新一次。
|
|
69
|
+
|
|
70
|
+
常用命令:
|
|
71
|
+
|
|
72
|
+
| 命令 | 用途 | 示例 |
|
|
73
|
+
|---|---|---|
|
|
74
|
+
| `ps` | 执行 PowerShell | `agent ps "Get-Process | Select-Object -First 5"` |
|
|
75
|
+
| `cmd` | 执行 cmd | `agent cmd "whoami"` |
|
|
76
|
+
| `open` | 确保应用主窗口存在并写入 session 缓存 | `agent open firefox --session crm-export-001` |
|
|
77
|
+
| `probe` | 探测关键目标是否出现 | `agent probe firefox --targets "Download Export,Start Date"` |
|
|
78
|
+
| `observe` | 返回窗口 compact 状态摘要 | `agent observe firefox --mode uia --targets "Username,Password"` |
|
|
79
|
+
| `click` | 语义点击目标 | `agent click firefox "Sign in"` |
|
|
80
|
+
| `type` | 定位目标后输入 | `agent type firefox "Username" "user@example.com"` |
|
|
81
|
+
| `key` | 发送单键 | `agent key firefox escape` |
|
|
82
|
+
| `hotkey` | 发送组合键 | `agent hotkey firefox ctrl,l` |
|
|
83
|
+
| `scroll` | 滚动窗口 | `agent scroll firefox --direction down --amount 3 --dispatch foreground` |
|
|
84
|
+
| `session-clear` | 清理窗口缓存 | `agent session-clear crm-export-001` |
|
|
85
|
+
|
|
86
|
+
同一个 GUI 任务建议固定一个 session:
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
python -m remotecli.cli agent open firefox --session crm-export-001
|
|
90
|
+
python -m remotecli.cli agent probe firefox --targets "Download Export,Start Date" --session crm-export-001
|
|
91
|
+
python -m remotecli.cli agent click firefox "Download Export" --session crm-export-001
|
|
92
|
+
python -m remotecli.cli agent session-clear crm-export-001
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
也可以用环境变量省略每条命令的 `--session`:
|
|
96
|
+
|
|
97
|
+
```powershell
|
|
98
|
+
$env:REMOTECLI_SESSION="crm-export-001"
|
|
99
|
+
python -m remotecli.cli agent probe firefox --targets "Download Export"
|
|
100
|
+
python -m remotecli.cli agent click firefox "Download Export"
|
|
101
|
+
python -m remotecli.cli agent session-clear
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
窗口缓存控制:
|
|
105
|
+
|
|
106
|
+
- `--refresh-window`:强制重新解析窗口并更新缓存。
|
|
107
|
+
- `--no-window-cache`:完全绕过缓存,适合多窗口排查。
|
|
108
|
+
- 不传 session:不读写窗口缓存。
|
|
109
|
+
|
|
110
|
+
### probe 和 observe
|
|
111
|
+
|
|
112
|
+
页面 ready check 优先用 `agent probe`,不要一上来扫完整页面。
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
python -m remotecli.cli agent probe firefox --targets "Download Export,Start Date" --mode smart
|
|
116
|
+
python -m remotecli.cli agent observe firefox --mode uia --targets "Username,Password,Sign in"
|
|
117
|
+
python -m remotecli.cli agent observe firefox --mode vision
|
|
118
|
+
python -m remotecli.cli agent observe firefox --mode som-full
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
模式含义:
|
|
122
|
+
|
|
123
|
+
| 模式 | 用途 |
|
|
124
|
+
|---|---|
|
|
125
|
+
| `uia` | 读取 UIA/AX 树,适合后台系统、普通表单、调试页面结构 |
|
|
126
|
+
| `vision` | 只截图,不遍历 UIA/SOM |
|
|
127
|
+
| `som-full` | 全量 YOLO/OCR + 标注图,仅用于 UIA 缺失后的兜底或调试 |
|
|
128
|
+
| `smart` | `probe` 默认模式,先 UIA,目标未命中再走 SOM/OCR |
|
|
129
|
+
|
|
130
|
+
`agent click/type` 使用独立 SmartFind 定位链路,不依赖 `observe` 返回的元素全集。如果 `observe` 结果里已经有目标元素,下一步直接行动,不要重复 observe。
|
|
131
|
+
|
|
132
|
+
## CUA 桌面控制
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
python -m remotecli.cli [global flags] cua <action> [args]
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
`cua` 是底层桌面控制入口。普通 Agent 优先用 `agent`;以下场景直接用 `cua`:
|
|
139
|
+
|
|
140
|
+
- 已经知道准确 `pid/window_id`。
|
|
141
|
+
- 需要坐标点击、右键、双击、拖拽、真实滚轮事件。
|
|
142
|
+
- 一个应用有多个窗口,需要人工选择窗口。
|
|
143
|
+
- 需要异步提交任务并保留 `trace_id`。
|
|
144
|
+
|
|
145
|
+
常用命令:
|
|
146
|
+
|
|
147
|
+
| 命令 | 用途 | 示例 |
|
|
148
|
+
|---|---|---|
|
|
149
|
+
| `list-apps` | 列出运行应用 | `cua list-apps --query Firefox` |
|
|
150
|
+
| `list-windows` | 列出窗口 | `cua list-windows --pid 17376` |
|
|
151
|
+
| `launch-app` | 启动应用 | `cua launch-app --name notepad.exe` |
|
|
152
|
+
| `bring-to-front` | 窗口置前 | `cua bring-to-front --pid 17376 --window-id 7014188` |
|
|
153
|
+
| `get-window-state` | 获取窗口状态或截图 | `cua get-window-state --pid 17376 --window-id 7014188 --mode uia` |
|
|
154
|
+
| `probe-window` | 探测关键目标 | `cua probe-window --pid 17376 --window-id 7014188 --targets "Save,Cancel"` |
|
|
155
|
+
| `click` | 语义或坐标点击 | `cua click --pid 17376 --window-id 7014188 --target 保存` |
|
|
156
|
+
| `type-text` | 输入文本 | `cua type-text --pid 17376 --window-id 7014188 --target 文件名 --text report.txt` |
|
|
157
|
+
| `set-value` | 设置控件值 | `cua set-value --pid 17376 --window-id 7014188 --target 数量 --value 10` |
|
|
158
|
+
| `hotkey` | 组合键 | `cua hotkey --pid 17376 --window-id 7014188 --keys ctrl,s` |
|
|
159
|
+
| `press-key` | 单键 | `cua press-key --pid 17376 --window-id 7014188 --key enter` |
|
|
160
|
+
| `scroll` | 滚动 | `cua scroll --pid 17376 --window-id 7014188 --direction down --amount 3 --dispatch foreground` |
|
|
161
|
+
| `move-mouse` | 验证屏幕坐标落点 | `cua move-mouse --x 500 --y 300` |
|
|
162
|
+
| `drag` | 按住拖拽 | `cua drag --pid 17376 --window-id 7014188 --from-x 100 --from-y 100 --to-x 400 --to-y 100` |
|
|
163
|
+
|
|
164
|
+
定位规则:
|
|
165
|
+
|
|
166
|
+
- 优先用 `--target` 语义定位,不要优先猜坐标。
|
|
167
|
+
- `click/type-text/set-value` 支持 `--locate-mode smart|uia|som`。
|
|
168
|
+
- `smart` 默认先 UIA-only,UIA 找不到才截图 + SOM/OCR。
|
|
169
|
+
- `uia` 适合可访问控件,速度最快。
|
|
170
|
+
- `som` 适合无障碍树缺失或视觉复杂页面。
|
|
171
|
+
- 坐标使用客户机物理屏幕像素,不依赖固定分辨率或 DPI。
|
|
172
|
+
- 坐标不确定时先 `move-mouse --x ... --y ...` 验证落点。
|
|
173
|
+
- 普通鼠标移动不要用 `drag`;只有明确需要按住拖拽时才用。
|
|
174
|
+
|
|
175
|
+
`get-window-state` 是唯一截图入口:
|
|
176
|
+
|
|
177
|
+
```bash
|
|
178
|
+
python -m remotecli.cli cua get-window-state --pid 17376 --window-id 7014188 --mode vision
|
|
179
|
+
python -m remotecli.cli cua get-window-state --pid 17376 --window-id 7014188 --mode som-full
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
如果 `click/type-text/set-value --target` 返回 `TARGET_NOT_RESOLVED`,通常表示目标不可见、页面未加载、被弹窗挡住或 UIA/SOM 都未命中。先 `get-window-state` 或 `agent observe` 看当前窗口,处理遮挡后再重试,不要重复点击背后的目标。
|
|
183
|
+
|
|
184
|
+
## Shell 远程命令
|
|
185
|
+
|
|
186
|
+
```bash
|
|
187
|
+
python -m remotecli.cli [global flags] shell <action> [args]
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
`shell` 走 `native.shell` capability,在目标 Runtime 节点本机执行。适合环境探测、短脚本、启动 Windows 应用;涉及桌面交互时,启动后继续用 `agent` 或 `cua` 操作窗口。
|
|
191
|
+
|
|
192
|
+
| 命令 | 用途 | 示例 |
|
|
193
|
+
|---|---|---|
|
|
194
|
+
| `info` | 获取目标机器环境 | `shell info` |
|
|
195
|
+
| `exec` | 执行单条命令 | `shell exec --cmd "whoami"` |
|
|
196
|
+
| `exec-script` | 执行多行脚本 | `shell exec-script --shell powershell --script "Get-Process | Select-Object -First 5"` |
|
|
197
|
+
|
|
198
|
+
PowerShell 脚本建议用单引号包住整段 `--script`,避免 `$_.Name` 被本地 shell 展开。
|
|
199
|
+
|
|
200
|
+
打开 Windows 应用时,不要猜 AppID,先查真实启动目标:
|
|
201
|
+
|
|
202
|
+
```bash
|
|
203
|
+
python -m remotecli.cli shell exec-script --shell powershell --script 'Get-StartApps | Where-Object {$_.Name -like "*微信*"}'
|
|
204
|
+
python -m remotecli.cli shell exec-script --shell powershell --script '$app = Get-StartApps | Where-Object {$_.Name -like "*微信*"} | Select-Object -First 1; Start-Process ("shell:AppsFolder\" + $app.AppID)'
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
## RPA 流程
|
|
208
|
+
|
|
209
|
+
```bash
|
|
210
|
+
python -m remotecli.cli [global flags] rpa <action> [args]
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
`rpa` 用于执行 Runtime 侧预定义的 Robot Framework 流程。当前可用流程:
|
|
214
|
+
|
|
215
|
+
| Flow ID | 任务 |
|
|
216
|
+
|---|---|
|
|
217
|
+
| `crm-transaction-filter` | `01 - Fill Transaction Date Range` |
|
|
218
|
+
|
|
219
|
+
示例:
|
|
220
|
+
|
|
221
|
+
```bash
|
|
222
|
+
python -m remotecli.cli --wait rpa run \
|
|
223
|
+
--flow crm-transaction-filter \
|
|
224
|
+
--task "01 - Fill Transaction Date Range" \
|
|
225
|
+
--param START_DATE=20260701 \
|
|
226
|
+
--param END_DATE=20260701
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
规则:
|
|
230
|
+
|
|
231
|
+
- 参数用重复的 `--param KEY=VALUE` 传入。
|
|
232
|
+
- Runtime 会把参数转为 Robot Framework 变量:`--variable KEY:VALUE`。
|
|
233
|
+
- Robot 文件里用 `${KEY}` 读取。
|
|
234
|
+
- 参数名必须匹配 `[A-Za-z_][A-Za-z0-9_]*`。
|
|
235
|
+
- 参数值按字符串传递;含空格或特殊字符时按当前 shell 规则给整个 `KEY=VALUE` 加引号。
|
|
236
|
+
|
|
237
|
+
## 结果和输出
|
|
238
|
+
|
|
239
|
+
底层 `cua` / `shell` / `rpa` 默认异步提交,返回:
|
|
240
|
+
|
|
241
|
+
```json
|
|
242
|
+
{"trace_id": "task_xxx", "status": "queued"}
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
查询结果:
|
|
246
|
+
|
|
247
|
+
```bash
|
|
248
|
+
python -m remotecli.cli result <trace_id>
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
自动等待结果:
|
|
252
|
+
|
|
253
|
+
```bash
|
|
254
|
+
python -m remotecli.cli --wait shell info
|
|
255
|
+
python -m remotecli.cli --wait --wait-timeout 60 cua click --pid 17376 --window-id 7014188 --target 保存
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
注意:`--wait` 必须放在 `shell` / `cua` / `rpa` 前。`agent ...` 默认已经等待最终结果,不需要顶层 `--wait`。
|
|
259
|
+
|
|
260
|
+
`agent` 命令输出会尽量压平成 AI 友好的 JSON:
|
|
261
|
+
|
|
262
|
+
```json
|
|
263
|
+
{
|
|
264
|
+
"ok": true,
|
|
265
|
+
"trace_id": "task_xxx",
|
|
266
|
+
"stdout": "...",
|
|
267
|
+
"stderr": "",
|
|
268
|
+
"exit_code": 0,
|
|
269
|
+
"json": null,
|
|
270
|
+
"error": ""
|
|
271
|
+
}
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
GUI 类 `agent` 命令还会带:
|
|
275
|
+
|
|
276
|
+
```json
|
|
277
|
+
{
|
|
278
|
+
"ok": true,
|
|
279
|
+
"action": "click",
|
|
280
|
+
"pid": 8748,
|
|
281
|
+
"window_id": 460902,
|
|
282
|
+
"title": "GitHub - Mozilla Firefox",
|
|
283
|
+
"window_cached": true
|
|
284
|
+
}
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
## AI 集成
|
|
288
|
+
|
|
289
|
+
推荐让 AI 通过 subprocess 调 CLI,最容易隔离依赖和认证配置:
|
|
290
|
+
|
|
291
|
+
```python
|
|
292
|
+
import json
|
|
293
|
+
import subprocess
|
|
294
|
+
|
|
295
|
+
BASE = [
|
|
296
|
+
"python", "-m", "remotecli.cli",
|
|
297
|
+
"--middleware", "http://10.0.0.5:9100",
|
|
298
|
+
"--tenant", "acme_shanghai",
|
|
299
|
+
"--node", "sh_win_01",
|
|
300
|
+
"--handle", "wch_v1_...",
|
|
301
|
+
]
|
|
302
|
+
|
|
303
|
+
def call_remotecli(args: list[str]) -> dict:
|
|
304
|
+
result = subprocess.run(BASE + args, capture_output=True, text=True, timeout=60)
|
|
305
|
+
result.check_returncode()
|
|
306
|
+
return json.loads(result.stdout)
|
|
307
|
+
|
|
308
|
+
call_remotecli(["agent", "ps", "whoami"])
|
|
309
|
+
call_remotecli(["agent", "click", "firefox", "Sign in"])
|
|
310
|
+
call_remotecli(["--wait", "shell", "info"])
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
也可以直接用 Python client:
|
|
314
|
+
|
|
315
|
+
```python
|
|
316
|
+
from remotecli.client import RemoteCliClient
|
|
317
|
+
|
|
318
|
+
client = RemoteCliClient(
|
|
319
|
+
middleware_url="http://10.0.0.5:9100",
|
|
320
|
+
tenant_id="acme_shanghai",
|
|
321
|
+
node_id="sh_win_01",
|
|
322
|
+
handle="wch_v1_...",
|
|
323
|
+
)
|
|
324
|
+
|
|
325
|
+
queued = client.submit("desktop.cua", "click", {
|
|
326
|
+
"pid": 17376,
|
|
327
|
+
"window_id": 7014188,
|
|
328
|
+
"target": "保存",
|
|
329
|
+
})
|
|
330
|
+
result = client.poll_result(queued["trace_id"])
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
## 典型流程
|
|
334
|
+
|
|
335
|
+
打开应用、输入并保存,普通 Agent 优先这样写:
|
|
336
|
+
|
|
337
|
+
```bash
|
|
338
|
+
python -m remotecli.cli agent open notepad --session note-001
|
|
339
|
+
python -m remotecli.cli agent type notepad "Text Editor" "hello world" --session note-001
|
|
340
|
+
python -m remotecli.cli agent hotkey notepad ctrl,s --session note-001
|
|
341
|
+
python -m remotecli.cli agent type notepad "文件名" "hello.txt" --session note-001
|
|
342
|
+
python -m remotecli.cli agent key notepad enter --session note-001
|
|
343
|
+
python -m remotecli.cli agent session-clear note-001
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
已有 `pid/window_id` 或需要底层调试时:
|
|
347
|
+
|
|
348
|
+
```bash
|
|
349
|
+
python -m remotecli.cli --wait cua get-window-state --pid <pid> --window-id <wid> --mode uia
|
|
350
|
+
python -m remotecli.cli --wait cua click --pid <pid> --window-id <wid> --target 保存 --locate-mode smart
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
## 错误处理
|
|
354
|
+
|
|
355
|
+
| 错误 | 含义 | 处理 |
|
|
356
|
+
|---|---|---|
|
|
357
|
+
| `AUTH_HANDLE_REQUIRED` | strict 模式下没传 handle | 加 `--handle wch_v1_...` |
|
|
358
|
+
| `AUTH_HANDLE_INVALID` | handle 无效或过期 | 重新签发 handle |
|
|
359
|
+
| `AUTH_TENANT_DENIED` | handle 不允许访问该 tenant | 检查 `--tenant` |
|
|
360
|
+
| `busy` / `409` | 节点被其他 Agent 租约占用 | 稍后重试或换 `--node` |
|
|
361
|
+
| `NODE_NO_RESPONSE` | Middleware 下发后 Runtime 无 ACK | 检查 Runtime、Broker、节点注册状态 |
|
|
362
|
+
| `Unknown capability` | 目标 capability 未注册 | 检查 Runtime 插件是否加载 |
|
|
363
|
+
| `TARGET_NOT_RESOLVED` | 目标不可见或定位失败 | 先观察窗口,处理弹窗/遮挡/页面加载后重试 |
|
|
364
|
+
|
|
365
|
+
## 常见问题
|
|
366
|
+
|
|
367
|
+
**截图在哪里?**
|
|
368
|
+
`cua get-window-state --mode vision` 返回 screenshot 元数据,例如 `local_path`、`size_bytes`、`width`、`height`。截图 PNG 保存在客户机本地 `runtime_state/screenshots/`。Agent 与 Runtime 同机时可直接读 `local_path`;跨机访问需要另行提供文件访问通道。
|
|
369
|
+
|
|
370
|
+
**handle 是必须的吗?**
|
|
371
|
+
取决于 Middleware 启动模式。demo mode 下 handle 可选;strict auth 模式下所有任务都必须带 handle。
|
|
372
|
+
|
|
373
|
+
**能同时控制多台客户机吗?**
|
|
374
|
+
能。不同 `--node` 指向不同客户机。一台客户机同一时刻只允许一个 Agent 独占控制。
|
|
375
|
+
|
|
376
|
+
**四个子文档还要维护吗?**
|
|
377
|
+
只维护速查和入口说明。完整规则集中在本文件,避免重复内容互相过期。
|
|
378
|
+
|
|
379
|
+
## 目录
|
|
380
|
+
|
|
381
|
+
```text
|
|
382
|
+
remotecli/
|
|
383
|
+
├── cli.py
|
|
384
|
+
├── client.py
|
|
385
|
+
├── agent.py
|
|
386
|
+
├── cua.py
|
|
387
|
+
├── shell.py
|
|
388
|
+
├── rpa.py
|
|
389
|
+
├── config/
|
|
390
|
+
│ └── agentremote.cli.toml
|
|
391
|
+
└── guides/
|
|
392
|
+
├── GUIDE.md # 主文档
|
|
393
|
+
├── agent.md # Agent 高层命令速查
|
|
394
|
+
├── cua.md # CUA 底层命令速查
|
|
395
|
+
├── shell.md # Shell 命令速查
|
|
396
|
+
└── rpa.md # RPA 流程速查
|
|
397
|
+
```
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# Agent 命令速查
|
|
2
|
+
|
|
3
|
+
完整规则见 [GUIDE.md](./GUIDE.md)。本文件只保留普通 AI Agent 最常用入口。
|
|
4
|
+
|
|
5
|
+
`agent` 是默认推荐入口:
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
python -m remotecli.cli agent <action> [args]
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
它会自动等待最终结果、解包 `result.output`,并在 GUI 操作前按应用名查找真实 `pid/window_id`。
|
|
12
|
+
|
|
13
|
+
## 什么时候用
|
|
14
|
+
|
|
15
|
+
| 目标 | 命令 |
|
|
16
|
+
|---|---|
|
|
17
|
+
| 执行 PowerShell | `agent ps "<script>"` |
|
|
18
|
+
| 执行 cmd | `agent cmd "<command>"` |
|
|
19
|
+
| 确保应用窗口存在 | `agent open <app>` |
|
|
20
|
+
| 判断按钮/输入框是否出现 | `agent probe <app> --targets "A,B"` |
|
|
21
|
+
| 看窗口 compact 状态 | `agent observe <app>` |
|
|
22
|
+
| 点击目标 | `agent click <app> "<target>"` |
|
|
23
|
+
| 输入文本 | `agent type <app> "<target>" "<text>"` |
|
|
24
|
+
| 单键 | `agent key <app> enter` |
|
|
25
|
+
| 组合键 | `agent hotkey <app> ctrl,l` |
|
|
26
|
+
| 滚动 | `agent scroll <app> --direction down --amount 3` |
|
|
27
|
+
| 清理窗口缓存 | `agent session-clear <session>` |
|
|
28
|
+
|
|
29
|
+
## 常用示例
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
python -m remotecli.cli agent ps "Get-Process | Select-Object -First 5"
|
|
33
|
+
python -m remotecli.cli agent open firefox --session crm-export-001
|
|
34
|
+
python -m remotecli.cli agent probe firefox --targets "Download Export,Start Date" --session crm-export-001
|
|
35
|
+
python -m remotecli.cli agent click firefox "Download Export" --session crm-export-001
|
|
36
|
+
python -m remotecli.cli agent session-clear crm-export-001
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## 关键规则
|
|
40
|
+
|
|
41
|
+
- `agent ...` 默认等待最终结果,不需要顶层 `--wait`。
|
|
42
|
+
- 同一个 GUI 任务建议固定一个 `--session`,避免每步重复查窗口。
|
|
43
|
+
- 页面 ready check 优先用 `probe`,不要先扫完整页面。
|
|
44
|
+
- `observe --mode uia` 用于查看页面结构;`--mode vision` 只截图;`--mode som-full` 只用于 UIA 缺失后的调试。
|
|
45
|
+
- `click/type` 有自己的 SmartFind 定位链路,不依赖 `observe` 返回完整元素列表。
|
|
46
|
+
- 多窗口手选、坐标点击、右键、拖拽、异步任务、固定 RPA 流程,降到底层 `cua` / `shell` / `rpa`。
|
|
47
|
+
|
|
48
|
+
## 窗口缓存
|
|
49
|
+
|
|
50
|
+
```powershell
|
|
51
|
+
$env:REMOTECLI_SESSION="crm-export-001"
|
|
52
|
+
python -m remotecli.cli agent probe firefox --targets "Start Date,End Date"
|
|
53
|
+
python -m remotecli.cli agent click firefox "Download Export"
|
|
54
|
+
python -m remotecli.cli agent session-clear
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
调试缓存:
|
|
58
|
+
|
|
59
|
+
- `--refresh-window`:强制重新解析并更新缓存。
|
|
60
|
+
- `--no-window-cache`:绕过缓存。
|
remotecli/guides/cua.md
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# CUA 命令速查
|
|
2
|
+
|
|
3
|
+
完整规则见 [GUIDE.md](./GUIDE.md)。本文件只保留底层桌面控制速查。
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
python -m remotecli.cli [global flags] cua <action> [args]
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
普通 AI Agent 优先用 `agent` 子命令。只有需要 `pid/window_id`、坐标、右键、拖拽、多窗口手选或异步任务时,直接用 `cua`。
|
|
10
|
+
|
|
11
|
+
## 常用命令
|
|
12
|
+
|
|
13
|
+
| 目标 | 命令示例 |
|
|
14
|
+
|---|---|
|
|
15
|
+
| 查运行应用 | `cua list-apps --query Firefox` |
|
|
16
|
+
| 查窗口 | `cua list-windows --pid 17376` |
|
|
17
|
+
| 启动应用 | `cua launch-app --name notepad.exe` |
|
|
18
|
+
| 前置窗口 | `cua bring-to-front --pid 17376 --window-id 7014188` |
|
|
19
|
+
| 获取 UIA 状态 | `cua get-window-state --pid 17376 --window-id 7014188 --mode uia` |
|
|
20
|
+
| 只截图 | `cua get-window-state --pid 17376 --window-id 7014188 --mode vision` |
|
|
21
|
+
| SOM/OCR 调试 | `cua get-window-state --pid 17376 --window-id 7014188 --mode som-full` |
|
|
22
|
+
| 探测目标 | `cua probe-window --pid 17376 --window-id 7014188 --targets "Save,Cancel"` |
|
|
23
|
+
| 语义点击 | `cua click --pid 17376 --window-id 7014188 --target 保存` |
|
|
24
|
+
| 输入文本 | `cua type-text --pid 17376 --window-id 7014188 --target 文件名 --text report.txt` |
|
|
25
|
+
| 设置控件值 | `cua set-value --pid 17376 --window-id 7014188 --target 数量 --value 10` |
|
|
26
|
+
| 热键 | `cua hotkey --pid 17376 --window-id 7014188 --keys ctrl,s` |
|
|
27
|
+
| 单键 | `cua press-key --pid 17376 --window-id 7014188 --key enter` |
|
|
28
|
+
| 滚动 | `cua scroll --pid 17376 --window-id 7014188 --direction down --amount 3 --dispatch foreground` |
|
|
29
|
+
| 验证坐标 | `cua move-mouse --x 500 --y 300` |
|
|
30
|
+
| 拖拽 | `cua drag --pid 17376 --window-id 7014188 --from-x 100 --from-y 100 --to-x 400 --to-y 100` |
|
|
31
|
+
|
|
32
|
+
底层命令默认异步返回 `trace_id`。需要等待时:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
python -m remotecli.cli --wait cua click --pid 17376 --window-id 7014188 --target 保存
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
`--wait` 必须放在 `cua` 前。
|
|
39
|
+
|
|
40
|
+
## 定位规则
|
|
41
|
+
|
|
42
|
+
- 优先用 `--target`,不要优先猜坐标。
|
|
43
|
+
- `click/type-text/set-value` 支持 `--locate-mode smart|uia|som`。
|
|
44
|
+
- `smart` 默认先 UIA-only,UIA 找不到才截图 + SOM/OCR。
|
|
45
|
+
- `uia` 适合可访问控件,速度最快。
|
|
46
|
+
- `som` 适合 UIA 缺失或视觉复杂页面。
|
|
47
|
+
- 坐标使用客户机物理屏幕像素。
|
|
48
|
+
- 坐标不确定时先 `move-mouse` 验证落点。
|
|
49
|
+
- 普通鼠标移动不要用 `drag`;只有明确需要按住拖拽时才用。
|
|
50
|
+
|
|
51
|
+
## 失败处理
|
|
52
|
+
|
|
53
|
+
`TARGET_NOT_RESOLVED` 表示目标不可见、页面未加载、被弹窗挡住或定位链路未命中。先观察窗口状态:
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
python -m remotecli.cli --wait cua get-window-state --pid 17376 --window-id 7014188 --mode uia
|
|
57
|
+
python -m remotecli.cli --wait cua get-window-state --pid 17376 --window-id 7014188 --mode vision
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
处理弹窗、遮挡或页面加载后再重试,不要重复点击背后的目标。
|
remotecli/guides/rpa.md
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# RPA 命令速查
|
|
2
|
+
|
|
3
|
+
完整规则见 [GUIDE.md](./GUIDE.md)。本文件只保留 Robot Framework 流程速查。
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
python -m remotecli.cli [global flags] rpa <action> [args]
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
`rpa` 用于执行 Runtime 侧已经注册的固定业务流程,不用于临时桌面操作。
|
|
10
|
+
|
|
11
|
+
## 常用命令
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
python -m remotecli.cli rpa list-flows
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
python -m remotecli.cli --wait rpa run \
|
|
19
|
+
--flow crm-transaction-filter \
|
|
20
|
+
--task "01 - Fill Transaction Date Range" \
|
|
21
|
+
--param START_DATE=20260701 \
|
|
22
|
+
--param END_DATE=20260701
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
当前流程:
|
|
26
|
+
|
|
27
|
+
| Flow ID | 任务 |
|
|
28
|
+
|---|---|
|
|
29
|
+
| `crm-transaction-filter` | `01 - Fill Transaction Date Range` |
|
|
30
|
+
|
|
31
|
+
## 参数规则
|
|
32
|
+
|
|
33
|
+
- 参数用重复的 `--param KEY=VALUE` 传入。
|
|
34
|
+
- Runtime 会转成 Robot Framework 变量:`--variable KEY:VALUE`。
|
|
35
|
+
- Robot 文件里用 `${KEY}` 读取。
|
|
36
|
+
- 参数名必须匹配 `[A-Za-z_][A-Za-z0-9_]*`。
|
|
37
|
+
- 参数值按字符串传递;含空格或特殊字符时给整个 `KEY=VALUE` 加引号。
|
|
38
|
+
|
|
39
|
+
## 等待结果
|
|
40
|
+
|
|
41
|
+
底层 `rpa` 默认异步返回 `trace_id`。自动等待时把 `--wait` 放在 `rpa` 前:
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
python -m remotecli.cli --wait --wait-timeout 120 rpa run --flow crm-transaction-filter --task "01 - Fill Transaction Date Range"
|
|
45
|
+
```
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# Shell 命令速查
|
|
2
|
+
|
|
3
|
+
完整规则见 [GUIDE.md](./GUIDE.md)。本文件只保留远程 Shell 速查。
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
python -m remotecli.cli [global flags] shell <action> [args]
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
`shell` 走 `native.shell` capability,在目标 Runtime 节点本机执行。适合环境探测、短脚本、启动应用;桌面交互继续用 `agent` 或 `cua`。
|
|
10
|
+
|
|
11
|
+
## 常用命令
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
python -m remotecli.cli --wait shell info
|
|
15
|
+
python -m remotecli.cli --wait shell exec --cmd "whoami"
|
|
16
|
+
python -m remotecli.cli --wait --wait-timeout 60 shell exec --cmd "dir C:\\"
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
执行脚本:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
python -m remotecli.cli --wait shell exec-script --shell powershell --script "Get-Process | Select-Object -First 5"
|
|
23
|
+
python -m remotecli.cli --wait shell exec-script --shell cmd --script "@echo off\r\necho Hello"
|
|
24
|
+
python -m remotecli.cli --wait shell exec-script --shell bash --script "echo hello; ls -la"
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
支持的 shell 取决于目标 Runtime 机器,通常包括 `cmd`、`powershell`、`pwsh`、`bash`、`sh`。
|
|
28
|
+
|
|
29
|
+
## 打开 Windows 应用
|
|
30
|
+
|
|
31
|
+
不要猜 AppID,先查真实启动目标:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
python -m remotecli.cli --wait shell exec-script --shell powershell --script 'Get-StartApps | Where-Object {$_.Name -like "*微信*"}'
|
|
35
|
+
python -m remotecli.cli --wait shell exec-script --shell powershell --script '$app = Get-StartApps | Where-Object {$_.Name -like "*微信*"} | Select-Object -First 1; Start-Process ("shell:AppsFolder\" + $app.AppID)'
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
然后用 `agent` 或 `cua` 操作窗口:
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
python -m remotecli.cli agent probe 微信 --targets "进入微信"
|
|
42
|
+
python -m remotecli.cli agent click 微信 "进入微信"
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## 关键规则
|
|
46
|
+
|
|
47
|
+
- 底层 `shell` 默认异步返回 `trace_id`;自动等待时把 `--wait` 放在 `shell` 前。
|
|
48
|
+
- PowerShell 脚本建议用单引号包住整段 `--script`,避免 `$_.Name` 被本地 shell 展开。
|
|
49
|
+
- 长时间任务设置 `--wait-timeout` 或底层命令自己的 `--timeout`。
|
remotecli/rpa.py
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"""
|
|
2
|
+
remotecli rpa — RPA 流程执行子命令.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
import re
|
|
8
|
+
from typing import Any, Dict
|
|
9
|
+
|
|
10
|
+
from .client import RemoteCliClient
|
|
11
|
+
|
|
12
|
+
_PARAM_NAME_RE = re.compile(r"^[A-Za-z_][A-Za-z0-9_]*$")
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class RpaCommands:
|
|
16
|
+
"""RPA 流程命令构建器。"""
|
|
17
|
+
|
|
18
|
+
def __init__(self, client: RemoteCliClient) -> None:
|
|
19
|
+
self._client = client
|
|
20
|
+
|
|
21
|
+
def run(
|
|
22
|
+
self,
|
|
23
|
+
flow: str,
|
|
24
|
+
task: str = "",
|
|
25
|
+
timeout_sec: int = 180,
|
|
26
|
+
params: Dict[str, Any] | None = None,
|
|
27
|
+
) -> Dict[str, Any]:
|
|
28
|
+
"""Execute an RPA flow."""
|
|
29
|
+
args: Dict[str, Any] = {"flow": flow, "task": task}
|
|
30
|
+
normalized_params = _normalize_params(params)
|
|
31
|
+
if normalized_params:
|
|
32
|
+
args["params"] = normalized_params
|
|
33
|
+
return self._client.submit(
|
|
34
|
+
capability_id=flow, # flow id IS the capability id
|
|
35
|
+
tool="run",
|
|
36
|
+
args=args,
|
|
37
|
+
timeout_sec=timeout_sec,
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
def list_flows(self) -> Dict[str, Any]:
|
|
41
|
+
"""List available RPA flows."""
|
|
42
|
+
caps = self._client.list_capabilities()
|
|
43
|
+
capabilities = caps.get("capabilities", [])
|
|
44
|
+
rpa_flows = [c for c in capabilities if c.get("runner") == "rpa"]
|
|
45
|
+
return {"flows": rpa_flows}
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def _normalize_params(params: Dict[str, Any] | None) -> Dict[str, str]:
|
|
49
|
+
if not params:
|
|
50
|
+
return {}
|
|
51
|
+
normalized: Dict[str, str] = {}
|
|
52
|
+
for key, value in params.items():
|
|
53
|
+
name = str(key).strip()
|
|
54
|
+
if not _PARAM_NAME_RE.match(name):
|
|
55
|
+
raise ValueError(f"invalid RPA param name: {name}")
|
|
56
|
+
normalized[name] = "" if value is None else str(value)
|
|
57
|
+
return normalized
|