agentmb 0.3.1 → 0.3.2
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/README.md +188 -4
- package/dist/browser/actions.d.ts +1 -1
- package/dist/browser/actions.d.ts.map +1 -1
- package/dist/browser/actions.js +4 -3
- package/dist/browser/actions.js.map +1 -1
- package/dist/browser/manager.d.ts +21 -0
- package/dist/browser/manager.d.ts.map +1 -1
- package/dist/browser/manager.js +127 -12
- package/dist/browser/manager.js.map +1 -1
- package/dist/cli/commands/actions.d.ts.map +1 -1
- package/dist/cli/commands/actions.js +37 -10
- package/dist/cli/commands/actions.js.map +1 -1
- package/dist/cli/commands/session.d.ts.map +1 -1
- package/dist/cli/commands/session.js +9 -0
- package/dist/cli/commands/session.js.map +1 -1
- package/dist/cli/index.js +1 -1
- package/dist/daemon/routes/actions.d.ts.map +1 -1
- package/dist/daemon/routes/actions.js +97 -12
- package/dist/daemon/routes/actions.js.map +1 -1
- package/dist/daemon/routes/interaction.d.ts.map +1 -1
- package/dist/daemon/routes/interaction.js +10 -1
- package/dist/daemon/routes/interaction.js.map +1 -1
- package/dist/daemon/routes/sessions.d.ts.map +1 -1
- package/dist/daemon/routes/sessions.js +107 -1
- package/dist/daemon/routes/sessions.js.map +1 -1
- package/dist/daemon/server.js +1 -1
- package/package.json +4 -2
- package/skills/agentmb/SKILL.md +541 -0
- package/skills/agentmb/references/authentication.md +180 -0
- package/skills/agentmb/references/browser-modes.md +167 -0
- package/skills/agentmb/references/commands.md +231 -0
- package/skills/agentmb/references/locator-modes.md +254 -0
- package/skills/agentmb/references/session-management.md +260 -0
|
@@ -0,0 +1,541 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: agentmb
|
|
3
|
+
description: >
|
|
4
|
+
Local browser automation daemon for AI agents. Use when the task requires
|
|
5
|
+
interacting with websites: navigate pages, fill forms, click buttons, take
|
|
6
|
+
screenshots, extract data, run web tests, log in to sites, or automate any
|
|
7
|
+
browser workflow.
|
|
8
|
+
Trigger phrases: "open a website", "fill out a form", "click a button",
|
|
9
|
+
"take a screenshot", "scrape data", "test this web app", "log in to",
|
|
10
|
+
"automate the browser", "browse to", "extract from the page".
|
|
11
|
+
allowed-tools:
|
|
12
|
+
- Bash(agentmb *)
|
|
13
|
+
- Bash(node dist/cli/index.js *)
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
# agentmb — AI Agent Quick Reference
|
|
17
|
+
|
|
18
|
+
> **For AI agents**: Read this file first. It covers 80% of use cases in one read.
|
|
19
|
+
> For deep reference, see [`references/`](./references/) (linked at the bottom).
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Core Workflow
|
|
24
|
+
|
|
25
|
+
Every agentmb task follows this loop:
|
|
26
|
+
|
|
27
|
+
```
|
|
28
|
+
1. Start daemon agentmb start (once per machine session)
|
|
29
|
+
2. Create session agentmb session new --profile <name> → returns <session-id>
|
|
30
|
+
3. Navigate agentmb navigate <session-id> <url>
|
|
31
|
+
4. Scan elements agentmb element-map <session-id> → returns e1, e2, e3…
|
|
32
|
+
5. Interact agentmb click <session-id> e3 --element-id
|
|
33
|
+
6. Re-scan agentmb element-map <session-id> (after page changes)
|
|
34
|
+
7. Close session agentmb session rm <session-id>
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
**Important**: Every command requires `<session-id>`. Get it from `session new` or `session list`.
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
# Minimal end-to-end example
|
|
41
|
+
agentmb start &
|
|
42
|
+
SID=$(agentmb session new --profile demo | grep -oP 'sess_\w+')
|
|
43
|
+
agentmb navigate $SID https://example.com
|
|
44
|
+
agentmb element-map $SID
|
|
45
|
+
agentmb screenshot $SID -o shot.png
|
|
46
|
+
agentmb session rm $SID
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
## Locator Mode — How to Choose
|
|
52
|
+
|
|
53
|
+
**Use this priority order. Start at 1, move to next only if needed.**
|
|
54
|
+
|
|
55
|
+
### Priority 1 — element-map + --element-id (default)
|
|
56
|
+
|
|
57
|
+
Works for most pages with visible text, links, or buttons.
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
agentmb element-map <session-id>
|
|
61
|
+
# → e1 [button] Submit
|
|
62
|
+
# → e2 [input] Email address
|
|
63
|
+
# → e3 [a] Sign in
|
|
64
|
+
|
|
65
|
+
agentmb click <session-id> e1 --element-id
|
|
66
|
+
agentmb fill <session-id> e2 "user@example.com" --element-id
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Use when: text-rich pages (docs, GitHub, dashboards, forms).
|
|
70
|
+
|
|
71
|
+
### Priority 2 — CSS Selector (when element-map labels are empty or unreliable)
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
agentmb click <session-id> "button[data-testid=submit]"
|
|
75
|
+
agentmb fill <session-id> "#email" "user@example.com"
|
|
76
|
+
agentmb get <session-id> text ".product-title"
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Use when: icon-only SPAs, dynamic class names, element-map returns `label_source=none`.
|
|
80
|
+
|
|
81
|
+
### Priority 3 — snapshot-map + --ref-id (for dynamic pages / run_steps)
|
|
82
|
+
|
|
83
|
+
Snapshot captures a point-in-time state; ref_id stays valid as long as the page hasn't navigated.
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
agentmb snapshot-map <session-id>
|
|
87
|
+
# → snap_000001:e1 [button] Login
|
|
88
|
+
# → snap_000001:e5 [input] Password
|
|
89
|
+
|
|
90
|
+
agentmb click <session-id> snap_000001:e1 --ref-id
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
Python SDK:
|
|
94
|
+
```python
|
|
95
|
+
snap = sess.snapshot_map()
|
|
96
|
+
btn = next(e for e in snap.elements if "Login" in (e.label or ""))
|
|
97
|
+
sess.click(ref_id=btn.ref_id)
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
Use when: you need to confirm element exists before acting, run_steps batch, or stale detection matters.
|
|
101
|
+
Stale ref (page changed): catch `409 stale_ref` → call `snapshot-map` again → retry.
|
|
102
|
+
|
|
103
|
+
### Priority 4 — click-at coordinates (last resort)
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
agentmb bbox <session-id> "#editor" # → center_x, center_y
|
|
107
|
+
agentmb click-at <session-id> 450 320
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
Use when: `contenteditable`, canvas, custom components, or all above fail.
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
114
|
+
## Essential Commands
|
|
115
|
+
|
|
116
|
+
### Session
|
|
117
|
+
|
|
118
|
+
| Command | Notes |
|
|
119
|
+
|---|---|
|
|
120
|
+
| `agentmb session new --profile <name>` | Named profile (persistent cookies) |
|
|
121
|
+
| `agentmb session new --ephemeral` | Temp profile, auto-deleted on close |
|
|
122
|
+
| `agentmb session new --browser-channel chrome` | Use system Chrome Stable |
|
|
123
|
+
| `agentmb session new --launch-mode attach --cdp-url http://127.0.0.1:9222` | CDP Attach to existing Chrome |
|
|
124
|
+
| `agentmb session new --proxy http://user:pass@host:8080` | Route all traffic through proxy |
|
|
125
|
+
| `agentmb session new --record-video` | Enable session video recording |
|
|
126
|
+
| `agentmb session new --allow-dir /path` | Allow `/utils/ls` access to a local dir (repeatable) |
|
|
127
|
+
| `agentmb session list` | List active sessions |
|
|
128
|
+
| `agentmb session rm <sid>` | Close and delete session |
|
|
129
|
+
| `agentmb session seal <sid>` | Prevent accidental deletion (423 on rm) |
|
|
130
|
+
|
|
131
|
+
### Navigation
|
|
132
|
+
|
|
133
|
+
| Command | Notes |
|
|
134
|
+
|---|---|
|
|
135
|
+
| `agentmb navigate <sid> <url>` | Navigate; `--wait-until load\|networkidle` |
|
|
136
|
+
| `agentmb back <sid>` / `forward <sid>` / `reload <sid>` | Browser history |
|
|
137
|
+
| `agentmb wait-url <sid> <pattern>` | Wait for URL to match pattern |
|
|
138
|
+
| `agentmb wait-text <sid> <text>` | Wait for text to appear |
|
|
139
|
+
| `agentmb wait-stable <sid>` | Network idle + DOM quiet |
|
|
140
|
+
|
|
141
|
+
### Element Interaction
|
|
142
|
+
|
|
143
|
+
| Command | Notes |
|
|
144
|
+
|---|---|
|
|
145
|
+
| `agentmb click <sid> <sel-or-eid>` | Click; use `--element-id` or `--ref-id` for scanned refs |
|
|
146
|
+
| `agentmb fill <sid> <sel-or-eid> <value>` | Fast fill (replace) |
|
|
147
|
+
| `agentmb type <sid> <sel-or-eid> <text>` | Type char by char; `--delay-ms <ms>` |
|
|
148
|
+
| `agentmb press <sid> <sel-or-eid> <key>` | Key combo: `Enter`, `Tab`, `Control+a` |
|
|
149
|
+
| `agentmb hover <sid> <sel-or-eid>` | Hover |
|
|
150
|
+
| `agentmb select <sid> <sel> <value>` | Select `<option>` in `<select>` |
|
|
151
|
+
| `agentmb check <sid> <sel-or-eid>` / `uncheck` | Checkbox / radio |
|
|
152
|
+
| `agentmb drag <sid> <source> <target>` | Drag-and-drop |
|
|
153
|
+
|
|
154
|
+
`<sel-or-eid>` accepts: CSS selector, `eN --element-id`, or `snap_XXXXXX:eN --ref-id`.
|
|
155
|
+
|
|
156
|
+
### Read / Assert
|
|
157
|
+
|
|
158
|
+
| Command | Notes |
|
|
159
|
+
|---|---|
|
|
160
|
+
| `agentmb get <sid> text <sel-or-eid>` | Read text / value / html / attr / box |
|
|
161
|
+
| `agentmb assert <sid> visible <sel-or-eid>` | Assert visible / enabled / checked |
|
|
162
|
+
| `agentmb extract <sid> <selector>` | Extract multiple elements as list |
|
|
163
|
+
| `agentmb eval <sid> <js-expr>` | Evaluate JavaScript; returns raw result |
|
|
164
|
+
|
|
165
|
+
### Observe
|
|
166
|
+
|
|
167
|
+
| Command | Notes |
|
|
168
|
+
|---|---|
|
|
169
|
+
| `agentmb screenshot <sid> -o out.png` | Screenshot; `--full-page` |
|
|
170
|
+
| `agentmb annotated-screenshot <sid> --highlight <sel>` | Screenshot with element overlays |
|
|
171
|
+
| `agentmb logs <sid> --tail 50` | Session audit log |
|
|
172
|
+
| `agentmb console-log <sid>` | Browser console entries |
|
|
173
|
+
| `agentmb page-errors <sid>` | Uncaught JS errors |
|
|
174
|
+
|
|
175
|
+
### Scroll
|
|
176
|
+
|
|
177
|
+
| Command | Notes |
|
|
178
|
+
|---|---|
|
|
179
|
+
| `agentmb scroll <sid> <sel-or-eid>` | Scroll; response has `scrolled`, `scrollable_hint` |
|
|
180
|
+
| `agentmb scroll-until <sid>` | Scroll until `--stop-selector` / `--stop-text` |
|
|
181
|
+
| `agentmb load-more-until <sid> <btn-sel> <item-sel>` | Repeatedly click load-more |
|
|
182
|
+
|
|
183
|
+
If `scrolled=false`, check `scrollable_hint` in response — it lists the top scrollable containers.
|
|
184
|
+
|
|
185
|
+
### Multi-Page (Tabs)
|
|
186
|
+
|
|
187
|
+
| Command | Notes |
|
|
188
|
+
|---|---|
|
|
189
|
+
| `agentmb pages list <sid>` | List all open tabs with IDs and URLs |
|
|
190
|
+
| `agentmb pages new <sid>` | Open a new tab → returns page-id |
|
|
191
|
+
| `agentmb pages switch <sid> <page-id>` | Switch active tab (changes default target) |
|
|
192
|
+
| `agentmb pages close <sid> <page-id>` | Close tab (last tab protected) |
|
|
193
|
+
|
|
194
|
+
**Direct page targeting (no tab switch needed)**: Pass `page_id` in the request body to any action route.
|
|
195
|
+
All major actions support `page_id`: navigate, click, fill, type, press, eval, screenshot, element_map, snapshot_map, scroll.
|
|
196
|
+
|
|
197
|
+
```python
|
|
198
|
+
# Target a specific tab WITHOUT switching active tab
|
|
199
|
+
sess.navigate("https://page2.example.com", page_id="page_abc123")
|
|
200
|
+
sess.element_map(page_id="page_abc123")
|
|
201
|
+
sess.click(element_id="e1", page_id="page_abc123")
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
```bash
|
|
205
|
+
# CLI: use --page-id flag
|
|
206
|
+
agentmb navigate $SID https://page2.example.com --page-id page_abc123
|
|
207
|
+
agentmb screenshot $SID -o p2.png --page-id page_abc123
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
---
|
|
211
|
+
|
|
212
|
+
## Common Patterns
|
|
213
|
+
|
|
214
|
+
### Pattern 1: Fill a Form and Submit
|
|
215
|
+
|
|
216
|
+
```bash
|
|
217
|
+
SID=<session-id>
|
|
218
|
+
agentmb navigate $SID https://example.com/login
|
|
219
|
+
agentmb element-map $SID
|
|
220
|
+
# Identify: e2 = email input, e3 = password input, e4 = Submit button
|
|
221
|
+
agentmb fill $SID e2 "user@example.com" --element-id
|
|
222
|
+
agentmb fill $SID e3 "password123" --element-id
|
|
223
|
+
agentmb click $SID e4 --element-id
|
|
224
|
+
agentmb wait-url $SID "**/dashboard**"
|
|
225
|
+
agentmb screenshot $SID -o after-login.png
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
### Pattern 2: Human Login Handoff (Reuse Login State)
|
|
229
|
+
|
|
230
|
+
```bash
|
|
231
|
+
# Step 1: One-time manual login
|
|
232
|
+
agentmb session new --profile myaccount
|
|
233
|
+
agentmb login <session-id> # opens headed browser window
|
|
234
|
+
# → Log in manually → press Enter in terminal
|
|
235
|
+
|
|
236
|
+
# Step 2: Subsequent runs reuse the saved profile
|
|
237
|
+
agentmb session new --profile myaccount # cookies already there
|
|
238
|
+
agentmb navigate <session-id> https://app.example.com/dashboard
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
Python SDK:
|
|
242
|
+
```python
|
|
243
|
+
# Export auth state after manual login
|
|
244
|
+
sess.storage_export("myaccount-state.json")
|
|
245
|
+
|
|
246
|
+
# Restore in future sessions
|
|
247
|
+
sess2 = client.sessions.create(profile="myaccount")
|
|
248
|
+
sess2.storage_import("myaccount-state.json")
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
### Pattern 3: Extract Data from a Page
|
|
252
|
+
|
|
253
|
+
```bash
|
|
254
|
+
SID=<session-id>
|
|
255
|
+
agentmb navigate $SID https://news.ycombinator.com
|
|
256
|
+
agentmb extract $SID ".titleline > a" # all article titles
|
|
257
|
+
agentmb get $SID text ".score:first-child" # first score
|
|
258
|
+
agentmb eval $SID "document.querySelectorAll('.rank').length" # JS eval
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
Python SDK:
|
|
262
|
+
```python
|
|
263
|
+
result = sess.extract(".titleline > a")
|
|
264
|
+
titles = [item["text"] for item in result.items]
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
### Pattern 4: run_steps Batch Execution
|
|
268
|
+
|
|
269
|
+
Execute multiple actions in one request. Supports `stop_on_error`.
|
|
270
|
+
|
|
271
|
+
```python
|
|
272
|
+
snap = sess.snapshot_map()
|
|
273
|
+
btn_ref = next(e.ref_id for e in snap.elements if "Login" in (e.label or ""))
|
|
274
|
+
|
|
275
|
+
result = sess.run_steps([
|
|
276
|
+
{"action": "navigate", "params": {"url": "https://example.com"}},
|
|
277
|
+
{"action": "click", "params": {"ref_id": btn_ref}},
|
|
278
|
+
{"action": "fill", "params": {"element_id": "e5", "value": "user@example.com"}},
|
|
279
|
+
{"action": "fill", "params": {"selector": "#pass", "value": "secret"}},
|
|
280
|
+
{"action": "press", "params": {"selector": "#pass", "key": "Enter"}},
|
|
281
|
+
{"action": "screenshot","params": {"format": "png"}},
|
|
282
|
+
], stop_on_error=True)
|
|
283
|
+
|
|
284
|
+
print(result.status, result.completed_steps)
|
|
285
|
+
for step in result.results:
|
|
286
|
+
if step.error:
|
|
287
|
+
print(f"Step {step.step} failed: {step.error}")
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
### Pattern 5: CDP Attach to Existing Chrome
|
|
291
|
+
|
|
292
|
+
```bash
|
|
293
|
+
# Start Chrome with remote debugging (Variant A: temp profile)
|
|
294
|
+
agentmb browser-launch --port 9222
|
|
295
|
+
|
|
296
|
+
# Attach
|
|
297
|
+
agentmb session new --launch-mode attach --cdp-url http://127.0.0.1:9222
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
Python SDK:
|
|
301
|
+
```python
|
|
302
|
+
sess = client.sessions.create(launch_mode="attach", cdp_url="http://127.0.0.1:9222")
|
|
303
|
+
sess.navigate("https://example.com")
|
|
304
|
+
sess.close() # only disconnects — Chrome stays alive
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
Use when: you need real Chrome fingerprint, extensions, or want to reuse your personal login state.
|
|
308
|
+
|
|
309
|
+
### Pattern 6: Multi-Tab Parallel Work (Switch-Based)
|
|
310
|
+
|
|
311
|
+
```python
|
|
312
|
+
# Open tabs, switch between them
|
|
313
|
+
page2_id = sess.new_page()
|
|
314
|
+
sess.switch_page(page2_id)
|
|
315
|
+
sess.navigate("https://other.example.com")
|
|
316
|
+
|
|
317
|
+
# Switch back to first tab
|
|
318
|
+
pages = sess.pages()
|
|
319
|
+
sess.switch_page(pages[0].page_id)
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
### Pattern 7: Single-Account Multi-Page Targeting (R09-C03)
|
|
323
|
+
|
|
324
|
+
**Key insight**: Use one session (one login) with multiple pages. Target specific pages directly
|
|
325
|
+
via `page_id` param — no tab switching needed. One agent can drive multiple pages concurrently.
|
|
326
|
+
|
|
327
|
+
```python
|
|
328
|
+
import asyncio
|
|
329
|
+
from agentmb import AsyncBrowserClient
|
|
330
|
+
|
|
331
|
+
async def run():
|
|
332
|
+
async with AsyncBrowserClient() as client:
|
|
333
|
+
# One session = one logged-in account
|
|
334
|
+
sess = await client.sessions.create(profile="gmail-account")
|
|
335
|
+
async with sess:
|
|
336
|
+
# Open three tabs
|
|
337
|
+
pages = await sess.pages()
|
|
338
|
+
p1 = pages[0].page_id # main tab
|
|
339
|
+
p2 = await sess.new_page() # returns page_id
|
|
340
|
+
p3 = await sess.new_page()
|
|
341
|
+
|
|
342
|
+
# Navigate each tab independently
|
|
343
|
+
await asyncio.gather(
|
|
344
|
+
sess.navigate("https://gmail.com/inbox", page_id=p1),
|
|
345
|
+
sess.navigate("https://gmail.com/sent", page_id=p2),
|
|
346
|
+
sess.navigate("https://gmail.com/drafts", page_id=p3),
|
|
347
|
+
)
|
|
348
|
+
|
|
349
|
+
# Screenshot all three without switching
|
|
350
|
+
shots = await asyncio.gather(
|
|
351
|
+
sess.screenshot(page_id=p1),
|
|
352
|
+
sess.screenshot(page_id=p2),
|
|
353
|
+
sess.screenshot(page_id=p3),
|
|
354
|
+
)
|
|
355
|
+
|
|
356
|
+
asyncio.run(run())
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
CLI equivalent (parallel via background jobs):
|
|
360
|
+
```bash
|
|
361
|
+
SID=<session-id>
|
|
362
|
+
P1=$(agentmb pages list $SID | grep active | awk '{print $1}')
|
|
363
|
+
P2=$(agentmb pages new $SID | grep page_id | awk '{print $2}')
|
|
364
|
+
|
|
365
|
+
agentmb navigate $SID https://site.com/page1 --page-id $P1 &
|
|
366
|
+
agentmb navigate $SID https://site.com/page2 --page-id $P2 &
|
|
367
|
+
wait
|
|
368
|
+
|
|
369
|
+
agentmb screenshot $SID -o p1.png --page-id $P1
|
|
370
|
+
agentmb screenshot $SID -o p2.png --page-id $P2
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
### Pattern 8: Anti-Ban / Humanization
|
|
374
|
+
|
|
375
|
+
For sites that detect automation, use these techniques:
|
|
376
|
+
|
|
377
|
+
```python
|
|
378
|
+
# 1. Use Chrome Stable (not Chromium) — real browser fingerprint
|
|
379
|
+
sess = client.sessions.create(
|
|
380
|
+
profile="my-account",
|
|
381
|
+
browser_channel="chrome", # system Chrome Stable
|
|
382
|
+
headless=False, # headed = visible window (harder to detect)
|
|
383
|
+
)
|
|
384
|
+
|
|
385
|
+
# 2. Human-like typing with delays
|
|
386
|
+
sess.fill(selector="#search", value="python tutorial",
|
|
387
|
+
fill_strategy="type", char_delay_ms=80) # ~80 ms per char
|
|
388
|
+
|
|
389
|
+
# 3. Mouse movement before click
|
|
390
|
+
sess.mouse_move(ref_id="snap_abc:e3") # smooth trajectory to target
|
|
391
|
+
sess.click(ref_id="snap_abc:e3")
|
|
392
|
+
|
|
393
|
+
# 4. Add realistic pauses between actions
|
|
394
|
+
import time
|
|
395
|
+
sess.click(element_id="e1")
|
|
396
|
+
time.sleep(1.2) # human-like pause
|
|
397
|
+
sess.fill(element_id="e2", value="hello world", fill_strategy="type", char_delay_ms=60)
|
|
398
|
+
time.sleep(0.8)
|
|
399
|
+
sess.click(element_id="e3") # submit
|
|
400
|
+
|
|
401
|
+
# 5. Use permissive policy (avoid rate-limit delays for your own throttling)
|
|
402
|
+
sess = client.sessions.create(profile="demo", policy="permissive")
|
|
403
|
+
|
|
404
|
+
# 6. Scroll before interacting (shows engagement pattern)
|
|
405
|
+
sess.scroll(selector="body", delta_y=300)
|
|
406
|
+
time.sleep(0.5)
|
|
407
|
+
sess.click(element_id="e5")
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
Key rules:
|
|
411
|
+
- Prefer `browser_channel="chrome"` over default Chromium for sites with fingerprint detection
|
|
412
|
+
- Use `fill_strategy="type"` for controlled inputs on SPAs (React/Vue/Angular) — avoids double-input bugs
|
|
413
|
+
- Use named profiles so each account has its own persistent session (cookies/storage)
|
|
414
|
+
- Avoid hammering the same endpoint — use `scroll_until` with `step_delay_ms` for pagination
|
|
415
|
+
- If blocked, use `agentmb login <sid>` to manually re-authenticate
|
|
416
|
+
|
|
417
|
+
### Pattern 9: Sensitive Domain Warning
|
|
418
|
+
|
|
419
|
+
`navigate` responses automatically include `sensitive_warning` when the target domain matches a sensitive category (financial, medical, gambling, adult, crypto). Use this to gate actions or log warnings:
|
|
420
|
+
|
|
421
|
+
```python
|
|
422
|
+
result = sess.navigate("https://mybank.example.com/")
|
|
423
|
+
raw = result.model_dump() if hasattr(result, "model_dump") else vars(result)
|
|
424
|
+
if raw.get("sensitive_warning"):
|
|
425
|
+
w = raw["sensitive_warning"]
|
|
426
|
+
print(f"[WARN] Sensitive domain ({w['category']}): {w['message']}")
|
|
427
|
+
# Optionally abort or require human confirmation
|
|
428
|
+
```
|
|
429
|
+
|
|
430
|
+
### Pattern 10: Network Route Mock with Regex
|
|
431
|
+
|
|
432
|
+
Use regex patterns for flexible URL interception. Enclose in `/regex/flags`:
|
|
433
|
+
|
|
434
|
+
```python
|
|
435
|
+
# Mock all JSON API endpoints
|
|
436
|
+
sess.add_route(r"/\/api\/.*\.json/i", mock={
|
|
437
|
+
"status": 200,
|
|
438
|
+
"content_type": "application/json",
|
|
439
|
+
"body": '{"mock": true}',
|
|
440
|
+
"delay_ms": 200, # simulate 200 ms latency
|
|
441
|
+
})
|
|
442
|
+
```
|
|
443
|
+
|
|
444
|
+
CLI:
|
|
445
|
+
```bash
|
|
446
|
+
agentmb route add $SID '/\/api\/.*\.json/i' --status 200 --body '{"mock":true}' --content-type application/json
|
|
447
|
+
```
|
|
448
|
+
|
|
449
|
+
### Pattern 11: Local File Scan via allow_dirs
|
|
450
|
+
|
|
451
|
+
Allow a session to scan specific local directories. Useful for agents that need to list generated reports, downloaded files, or workspace contents:
|
|
452
|
+
|
|
453
|
+
```python
|
|
454
|
+
import os, tempfile
|
|
455
|
+
|
|
456
|
+
tmpdir = "/tmp/agent-workspace"
|
|
457
|
+
os.makedirs(tmpdir, exist_ok=True)
|
|
458
|
+
|
|
459
|
+
sess = client.sessions.create(profile="demo", allow_dirs=[tmpdir])
|
|
460
|
+
|
|
461
|
+
# List directory contents (depth 2)
|
|
462
|
+
import requests
|
|
463
|
+
r = requests.get(f"http://127.0.0.1:19315/api/v1/utils/ls",
|
|
464
|
+
params={"session_id": sess.id, "path": tmpdir, "depth": "2"})
|
|
465
|
+
for entry in r.json()["entries"]:
|
|
466
|
+
print(entry["name"], entry["type"], entry.get("size"))
|
|
467
|
+
```
|
|
468
|
+
|
|
469
|
+
Access outside allowed dirs returns `403`. Sessions without `allow_dirs` always return `403`.
|
|
470
|
+
|
|
471
|
+
---
|
|
472
|
+
|
|
473
|
+
## Python SDK Quick Reference
|
|
474
|
+
|
|
475
|
+
```python
|
|
476
|
+
from agentmb import BrowserClient, AsyncBrowserClient
|
|
477
|
+
|
|
478
|
+
# Sync
|
|
479
|
+
with BrowserClient(base_url="http://127.0.0.1:19315") as client:
|
|
480
|
+
sess = client.sessions.create(profile="demo", headless=True)
|
|
481
|
+
sess.navigate("https://example.com")
|
|
482
|
+
shot = sess.screenshot()
|
|
483
|
+
shot.save("out.png")
|
|
484
|
+
result = sess.extract("h1")
|
|
485
|
+
print(result.items)
|
|
486
|
+
sess.close()
|
|
487
|
+
|
|
488
|
+
# Async
|
|
489
|
+
async with AsyncBrowserClient(base_url="http://127.0.0.1:19315") as client:
|
|
490
|
+
sess = await client.sessions.create(profile="demo")
|
|
491
|
+
async with sess:
|
|
492
|
+
await sess.navigate("https://example.com")
|
|
493
|
+
title = await sess.eval("document.title")
|
|
494
|
+
```
|
|
495
|
+
|
|
496
|
+
Key session options:
|
|
497
|
+
```python
|
|
498
|
+
client.sessions.create(
|
|
499
|
+
profile="name", # named persistent profile
|
|
500
|
+
ephemeral=True, # temp profile (no persistence)
|
|
501
|
+
headless=True, # headless mode (default)
|
|
502
|
+
browser_channel="chrome",# system Chrome Stable
|
|
503
|
+
launch_mode="attach", # CDP Attach
|
|
504
|
+
cdp_url="http://...", # required for attach mode
|
|
505
|
+
accept_downloads=True, # enable file downloads
|
|
506
|
+
policy="permissive", # rate limit policy: safe|permissive|disabled
|
|
507
|
+
proxy_url="http://...", # session-level proxy (R09)
|
|
508
|
+
record_video=True, # enable video recording (R09)
|
|
509
|
+
allow_dirs=["/tmp/data"],# whitelist for /utils/ls file scan (R09)
|
|
510
|
+
)
|
|
511
|
+
```
|
|
512
|
+
|
|
513
|
+
---
|
|
514
|
+
|
|
515
|
+
## Error Recovery
|
|
516
|
+
|
|
517
|
+
| Error | Meaning | Fix |
|
|
518
|
+
|---|---|---|
|
|
519
|
+
| `404 session not found` | Session ID invalid or expired | `session list` → use valid ID |
|
|
520
|
+
| `422` with `recovery_hint` | Action failed (timeout, not found, overlay) | Follow `recovery_hint` in response |
|
|
521
|
+
| `409 stale_ref` | snapshot-map ref_id expired (page navigated) | Call `snapshot-map` again, retry with new ref_id |
|
|
522
|
+
| `400 preflight_failed` | Invalid session parameters | Check field + constraint in error body |
|
|
523
|
+
| `403 sensitive blocked` | Safe policy blocking sensitive action | Use `agentmb policy <sid> permissive` or pass `sensitive: false` |
|
|
524
|
+
| `403 No allowed directories` | `/utils/ls` called but session has no `allow_dirs` | Re-create session with `--allow-dir <path>` or `allow_dirs=[...]` |
|
|
525
|
+
| `403 path not within allowed` | `/utils/ls` path is outside the whitelist | Use a path inside one of the configured `allow_dirs` |
|
|
526
|
+
| `423 session_sealed` | Session is sealed | Unseal via API or use a different session |
|
|
527
|
+
| `sensitive_warning` in navigate response | Target domain matched a sensitive category | Log warning; optionally gate further actions or require human confirmation |
|
|
528
|
+
|
|
529
|
+
---
|
|
530
|
+
|
|
531
|
+
## References
|
|
532
|
+
|
|
533
|
+
For deeper detail, see `skills/agentmb/references/`:
|
|
534
|
+
|
|
535
|
+
| File | When to read |
|
|
536
|
+
|---|---|
|
|
537
|
+
| [`locator-modes.md`](./references/locator-modes.md) | Full locator priority guide, `label_source` chain, stale_ref recovery, `ref_id` format |
|
|
538
|
+
| [`commands.md`](./references/commands.md) | Complete CLI command table by category (all flags) |
|
|
539
|
+
| [`session-management.md`](./references/session-management.md) | Multi-page, multi-agent, session lifecycle, policy |
|
|
540
|
+
| [`browser-modes.md`](./references/browser-modes.md) | Managed Chromium / Chrome Stable / CDP Attach deep dive |
|
|
541
|
+
| [`authentication.md`](./references/authentication.md) | Human login handoff, profile persistence, storage export/import |
|