browsemind 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +30 -0
- package/README.md +896 -0
- package/bin/browsemind.js +135 -0
- package/package.json +54 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
GNU AFFERO GENERAL PUBLIC LICENSE
|
|
2
|
+
Version 3, 19 November 2007
|
|
3
|
+
|
|
4
|
+
Copyright (C) 2026 browsemind Contributors
|
|
5
|
+
|
|
6
|
+
This program is free software: you can redistribute it and/or modify
|
|
7
|
+
it under the terms of the GNU Affero General Public License as published
|
|
8
|
+
by the Free Software Foundation, either version 3 of the License, or
|
|
9
|
+
(at your option) any later version.
|
|
10
|
+
|
|
11
|
+
This program is distributed in the hope that it will be useful,
|
|
12
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
13
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
14
|
+
GNU Affero General Public License for more details.
|
|
15
|
+
|
|
16
|
+
You should have received a copy of the GNU Affero General Public License
|
|
17
|
+
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
18
|
+
|
|
19
|
+
Full license text: https://www.gnu.org/licenses/agpl-3.0.txt
|
|
20
|
+
|
|
21
|
+
The above copyright notice and this permission notice shall be included in all
|
|
22
|
+
copies or substantial portions of the Software.
|
|
23
|
+
|
|
24
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
25
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
26
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
27
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
28
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
29
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
30
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,896 @@
|
|
|
1
|
+
# BrowseMind 🤖 — LLM Browser Automation Agent
|
|
2
|
+
|
|
3
|
+
> **Navigate, search, extract, and automate any website using natural language.**
|
|
4
|
+
> Powered by Crawl4AI and LiteLLM — the agent decides everything, you just describe what you need.
|
|
5
|
+
|
|
6
|
+
<div align="center">
|
|
7
|
+
|
|
8
|
+
[](https://www.python.org/downloads/)
|
|
9
|
+
[](https://github.com/prokopis3/browsemind/releases)
|
|
10
|
+
[](LICENSE)
|
|
11
|
+
[](https://github.com/unclecode/crawl4ai)
|
|
12
|
+
[](https://semver.org/spec/v2.0.0.html)
|
|
13
|
+
[](https://www.conventionalcommits.org/)
|
|
14
|
+
[](https://keepachangelog.com/en/1.1.0/)
|
|
15
|
+
[](https://github.com/prokopis3/browsemind/actions)
|
|
16
|
+
**[Installation](#installation)** • **[Quickstart](#rocket-quickstart)** • **[CLI Reference](#computer-cli-reference)** • **[Features](#sparkles-features)** • **[Architecture](#architecture)** • **[Configuration](#wrench-configuration)** • **[API](run_api.py)** • **[Roadmap](ROADMAP.md)**
|
|
17
|
+
|
|
18
|
+
</div>
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## 📋 Table of Contents
|
|
23
|
+
|
|
24
|
+
- [Installation](#installation)
|
|
25
|
+
- [Quickstart](#rocket-quickstart)
|
|
26
|
+
- [CLI Reference](#computer-cli-reference)
|
|
27
|
+
- [Features](#sparkles-features)
|
|
28
|
+
- [Architecture](#architecture)
|
|
29
|
+
- [Python API](#snake-python-api)
|
|
30
|
+
- [Configuration](#wrench-configuration)
|
|
31
|
+
- [Testing](#microscope-testing)
|
|
32
|
+
- [Project Structure](#open_file_folder-project-structure)
|
|
33
|
+
- [Contributing](#handshake-contributing)
|
|
34
|
+
- [License](#page_with_curl-license)
|
|
35
|
+
- [Disclaimer](#disclaimer)
|
|
36
|
+
- [Citations](#-citations-1)
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## Installation
|
|
41
|
+
|
|
42
|
+
### Requirements
|
|
43
|
+
|
|
44
|
+
- **Python 3.11+**
|
|
45
|
+
- **Chrome/Chromium** — installed automatically by Crawl4AI on first run, or manually via [Chrome for Testing](https://developer.chrome.com/blog/chrome-for-testing/)
|
|
46
|
+
- **Playwright** — installed via `playwright install chromium` (auto-setup with Crawl4AI)
|
|
47
|
+
|
|
48
|
+
<details>
|
|
49
|
+
<summary><strong>Package Managers</strong></summary>
|
|
50
|
+
|
|
51
|
+
### pip (recommended)
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
pip install browsemind
|
|
55
|
+
browsemind doctor # Verify installation
|
|
56
|
+
browsemind --task "Open example.com and screenshot it"
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### uv
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
uv tool install browsemind
|
|
63
|
+
browsemind doctor
|
|
64
|
+
browsemind --task "Open example.com and screenshot it"
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### npm
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
npm install -g browsemind
|
|
71
|
+
browsemind doctor
|
|
72
|
+
browsemind --task "Open example.com and screenshot it"
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### Homebrew (macOS)
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
brew install browsemind/browsemind/browsemind
|
|
79
|
+
browsemind doctor
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### Chocolatey (Windows)
|
|
83
|
+
|
|
84
|
+
```powershell
|
|
85
|
+
choco install browsemind
|
|
86
|
+
browsemind doctor
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Scoop (Windows)
|
|
90
|
+
|
|
91
|
+
```powershell
|
|
92
|
+
scoop bucket add browsemind https://github.com/prokopis3/scoop-browsemind
|
|
93
|
+
scoop install browsemind
|
|
94
|
+
browsemind doctor
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
</details>
|
|
98
|
+
|
|
99
|
+
<details>
|
|
100
|
+
<summary><strong>Development & Quick Start</strong></summary>
|
|
101
|
+
|
|
102
|
+
### From Source (development)
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
git clone https://github.com/prokopis3/browsemind.git
|
|
106
|
+
cd browsemind
|
|
107
|
+
|
|
108
|
+
# Create virtual environment
|
|
109
|
+
python -m venv .venv
|
|
110
|
+
source .venv/bin/activate # Linux/macOS
|
|
111
|
+
.venv\Scripts\activate # Windows
|
|
112
|
+
|
|
113
|
+
# Install
|
|
114
|
+
uv pip install -e .
|
|
115
|
+
|
|
116
|
+
# Install Playwright browsers
|
|
117
|
+
playwright install chromium
|
|
118
|
+
|
|
119
|
+
# Verify
|
|
120
|
+
browsemind doctor
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### Quick Start (no install)
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
npx browsemind doctor
|
|
127
|
+
npx browsemind --task "Open example.com and screenshot it"
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
</details>
|
|
131
|
+
|
|
132
|
+
<details>
|
|
133
|
+
<summary><strong>Updating & Diagnostics</strong></summary>
|
|
134
|
+
|
|
135
|
+
### Updating
|
|
136
|
+
|
|
137
|
+
Upgrade to the latest version:
|
|
138
|
+
|
|
139
|
+
```bash
|
|
140
|
+
browsemind upgrade
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
Auto-detects your installation method (pip, uv, npm, Homebrew, Chocolatey, Scoop) and runs the appropriate update command. Displays the version change on success.
|
|
144
|
+
|
|
145
|
+
To check for updates without upgrading:
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
browsemind upgrade --check
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
### Doctor — Diagnose Your Installation
|
|
152
|
+
|
|
153
|
+
Run `doctor` whenever something stops working unexpectedly or after upgrades:
|
|
154
|
+
|
|
155
|
+
```bash
|
|
156
|
+
browsemind doctor # Full diagnosis
|
|
157
|
+
browsemind doctor --offline --quick # Local-only, fastest
|
|
158
|
+
browsemind doctor --fix # Also run destructive repairs
|
|
159
|
+
browsemind doctor --json # Structured output for agents
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
Checks: environment, Chrome install, config files, security, network reachability, and a live headless launch test. Exit code `0` if all pass, `1` if any fail.
|
|
163
|
+
|
|
164
|
+
</details>
|
|
165
|
+
|
|
166
|
+
---
|
|
167
|
+
|
|
168
|
+
## 🚀 Quickstart
|
|
169
|
+
|
|
170
|
+
### 1. Set Your API Key
|
|
171
|
+
|
|
172
|
+
```bash
|
|
173
|
+
# Copy the example env file
|
|
174
|
+
cp llm.env.example llm.env
|
|
175
|
+
|
|
176
|
+
# Edit llm.env with at least one API key:
|
|
177
|
+
# DEEPSEEK_API_KEY=sk-your-deepseek-key
|
|
178
|
+
# OPENAI_API_KEY=sk-your-openai-key
|
|
179
|
+
# GROQ_API_KEY=gsk-your-groq-key
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
### 2. Run Your First Task
|
|
183
|
+
|
|
184
|
+
```bash
|
|
185
|
+
# Browse and screenshot
|
|
186
|
+
browsemind --task "Navigate to example.com and take a screenshot"
|
|
187
|
+
|
|
188
|
+
# Extract data
|
|
189
|
+
browsemind --task "Go to quotes.toscrape.com and extract all quotes" --headless
|
|
190
|
+
|
|
191
|
+
# Search + extract
|
|
192
|
+
browsemind --task "Search for Python async programming and return the top 3 results"
|
|
193
|
+
|
|
194
|
+
# Deep crawl a catalog
|
|
195
|
+
browsemind --task "Extract all product titles and prices" --url https://books.toscrape.com --discover
|
|
196
|
+
|
|
197
|
+
# Fast content extraction (Queen Reader — no LLM, no browser wait)
|
|
198
|
+
browsemind --task "Read the text from example.com"
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
### 3. Try Command Mode
|
|
202
|
+
|
|
203
|
+
```bash
|
|
204
|
+
browsemind open https://example.com
|
|
205
|
+
browsemind snapshot
|
|
206
|
+
browsemind screenshot
|
|
207
|
+
browsemind close
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
---
|
|
211
|
+
|
|
212
|
+
## 💻 CLI Reference
|
|
213
|
+
|
|
214
|
+
<details>
|
|
215
|
+
<summary><strong>Task Mode (AI Agent)</strong></summary>
|
|
216
|
+
|
|
217
|
+
```bash
|
|
218
|
+
browsemind --task "Extract all product names and prices" --url https://books.toscrape.com
|
|
219
|
+
browsemind --task "Find the pricing page and return the prices" --url https://example.com
|
|
220
|
+
browsemind --task "Extract all articles from the blog" --save json --output-dir ./output
|
|
221
|
+
browsemind --task "Access the dashboard and download the report" --url https://example.com/login --login
|
|
222
|
+
browsemind --task "Capture the full page" --url https://example.com --vision-tile
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
**Options:**
|
|
226
|
+
|
|
227
|
+
| Flag | Description |
|
|
228
|
+
|------|-------------|
|
|
229
|
+
| `--task`, `-t` | Natural language task description |
|
|
230
|
+
| `--url` | Starting URL |
|
|
231
|
+
| `--headless` | Run browser in headless mode |
|
|
232
|
+
| `--max-steps` | Maximum agent steps (default: 30) |
|
|
233
|
+
| `--save json/csv/both` | Save extracted data to file |
|
|
234
|
+
| `--screenshot` | Save screenshot after extraction |
|
|
235
|
+
| `--pdf` | Generate PDF of the page |
|
|
236
|
+
| `--markdown` | Generate markdown summary |
|
|
237
|
+
| `--discover` | Deep crawl domain discovery |
|
|
238
|
+
| `--discover-max-pages` | Max pages for discovery (default: 50) |
|
|
239
|
+
| `--login` | Force interactive login mode |
|
|
240
|
+
| `--json` | JSON output format |
|
|
241
|
+
| `--verbose`, `-v` | Verbose output |
|
|
242
|
+
|
|
243
|
+
</details>
|
|
244
|
+
|
|
245
|
+
<details>
|
|
246
|
+
<summary><strong>Command Mode — Core & Interactions</strong></summary>
|
|
247
|
+
|
|
248
|
+
#### Core
|
|
249
|
+
|
|
250
|
+
```bash
|
|
251
|
+
browsemind open <url> # Navigate to URL
|
|
252
|
+
browsemind fetch <url> # Fetch webpage content
|
|
253
|
+
browsemind snapshot # Get page state (element refs, text, URL)
|
|
254
|
+
browsemind screenshot [path] # Take a screenshot
|
|
255
|
+
browsemind close # Close browser
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
#### Interactions — use element refs from `snapshot`
|
|
259
|
+
|
|
260
|
+
```bash
|
|
261
|
+
browsemind click @e3 # Click element by ref
|
|
262
|
+
browsemind fill @e2 "hello world" # Clear and fill input
|
|
263
|
+
browsemind type @e2 "text" # Type into element
|
|
264
|
+
browsemind press Enter # Press keyboard key
|
|
265
|
+
browsemind scroll down # Scroll page
|
|
266
|
+
browsemind highlight .product-card # Highlight element
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
</details>
|
|
270
|
+
|
|
271
|
+
<details>
|
|
272
|
+
<summary><strong>Command Mode — Page Info, Tabs & Debug</strong></summary>
|
|
273
|
+
|
|
274
|
+
#### Page Information
|
|
275
|
+
|
|
276
|
+
```bash
|
|
277
|
+
browsemind get title # Page title
|
|
278
|
+
browsemind get url # Current URL
|
|
279
|
+
browsemind get text h1 # Element text
|
|
280
|
+
browsemind get html .content # Element HTML
|
|
281
|
+
browsemind get count .product # Element count
|
|
282
|
+
browsemind is visible .loading # Check visibility
|
|
283
|
+
browsemind cookies list # List cookies
|
|
284
|
+
browsemind storage get key # localStorage value
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
#### Tabs & Navigation
|
|
288
|
+
|
|
289
|
+
```bash
|
|
290
|
+
browsemind tab list # List open tabs
|
|
291
|
+
browsemind tab new <url> # Open new tab
|
|
292
|
+
browsemind tab switch 2 # Switch to tab
|
|
293
|
+
browsemind back # Go back
|
|
294
|
+
browsemind forward # Go forward
|
|
295
|
+
browsemind reload # Reload page
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
#### CDP & Debug
|
|
299
|
+
|
|
300
|
+
```bash
|
|
301
|
+
browsemind cdp # Get CDP WebSocket URL
|
|
302
|
+
browsemind console list # View JS console messages
|
|
303
|
+
browsemind errors list # View page errors
|
|
304
|
+
browsemind inspect # Open Chrome DevTools
|
|
305
|
+
browsemind pdf page.pdf # Save page as PDF
|
|
306
|
+
browsemind trace start # Start performance tracing
|
|
307
|
+
browsemind wait 5 # Wait N seconds
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
</details>
|
|
311
|
+
|
|
312
|
+
<details>
|
|
313
|
+
<summary><strong>Command Mode — Maintenance, Plugins & Fetch</strong></summary>
|
|
314
|
+
|
|
315
|
+
#### Setup & Maintenance
|
|
316
|
+
|
|
317
|
+
```bash
|
|
318
|
+
browsemind upgrade # Upgrade to latest version
|
|
319
|
+
browsemind upgrade --check # Check version without upgrading
|
|
320
|
+
browsemind doctor # Diagnose installation
|
|
321
|
+
browsemind doctor --fix # Diagnose + repair
|
|
322
|
+
browsemind doctor --json # Structured JSON output
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
#### Skills, Plugins & MCP
|
|
326
|
+
|
|
327
|
+
```bash
|
|
328
|
+
browsemind skills list # List installed skills
|
|
329
|
+
browsemind skills add <source> # Install skill from GitHub/URL
|
|
330
|
+
browsemind skills get <name> # Show skill details
|
|
331
|
+
browsemind skills remove <name> # Uninstall skill
|
|
332
|
+
|
|
333
|
+
browsemind plugin list # List installed plugins
|
|
334
|
+
browsemind plugin add <name> # Install plugin
|
|
335
|
+
browsemind plugin run <name> # Execute plugin
|
|
336
|
+
|
|
337
|
+
browsemind mcp --tools all # Start MCP server
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
#### Fetch Options
|
|
341
|
+
|
|
342
|
+
```bash
|
|
343
|
+
browsemind fetch <url> --format markdown # Default
|
|
344
|
+
browsemind fetch <url> --format json # Structured JSON
|
|
345
|
+
browsemind fetch <url> --format screenshot # Screenshot
|
|
346
|
+
browsemind fetch --search "query" # Search then fetch
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
</details>
|
|
350
|
+
|
|
351
|
+
---
|
|
352
|
+
|
|
353
|
+
## ✨ Features
|
|
354
|
+
|
|
355
|
+
<details>
|
|
356
|
+
<summary><strong>🧠 LLM Decision Engine</strong></summary>
|
|
357
|
+
|
|
358
|
+
`AgentBrain` uses LiteLLM to observe, think, decide, and verify — accuracy over cost. The system prompt is a compact **97-line / ~959-token decision tree** (was 580 lines / ~10K tokens — 6x smaller). The LLM chooses from **141 ActionType enum values** covering every pattern in the [Dynamic Data Extraction Guide](docs/DYNAMIC_DATA_EXTRACTION_GUIDE.md).
|
|
359
|
+
|
|
360
|
+
</details>
|
|
361
|
+
|
|
362
|
+
<details>
|
|
363
|
+
<summary><strong>🌐 Intelligent Browser Automation</strong></summary>
|
|
364
|
+
|
|
365
|
+
Full Playwright integration via Crawl4AI with anti-bot evasion, stealth mode, managed browser profiles, and persistent sessions. The **PageNavigator** provides a 6-strategy escalation chain:
|
|
366
|
+
|
|
367
|
+
```
|
|
368
|
+
DomainGraph cache → smart goto → navigate_js → proxy escalation → undetected browser → fallback fetch
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
Cloudflare, Akamai, CAPTCHA, and WAF detection built in.
|
|
372
|
+
|
|
373
|
+
</details>
|
|
374
|
+
|
|
375
|
+
<details>
|
|
376
|
+
<summary><strong>📊 Multi-Cascade Extraction (18 Pipelines)</strong></summary>
|
|
377
|
+
|
|
378
|
+
Cost-ascending extraction cascade — LLM is the **LAST** resort:
|
|
379
|
+
|
|
380
|
+
```
|
|
381
|
+
Identity → QueenReader → Markdown → CSS → XPath → Regex → Cosine → LLM → Vision
|
|
382
|
+
```
|
|
383
|
+
|
|
384
|
+
| Pipeline | Cost | Method |
|
|
385
|
+
|----------|------|--------|
|
|
386
|
+
| **Identity** (pass-through) | $0 | `NoExtractionStrategy` — raw content |
|
|
387
|
+
| **Queen Reader** | $0 | DOMContentLoaded fast path — no schema, no LLM, no vision |
|
|
388
|
+
| **CSS Extraction** | $0 | `JsonCssExtractionStrategy` — structured lists |
|
|
389
|
+
| **XPath Extraction** | $0 | `JsonXPathExtractionStrategy` — complex DOM |
|
|
390
|
+
| **Regex Extraction** | $0 | `RegexExtractionStrategy` — 23 built-in patterns |
|
|
391
|
+
| **Cosine Extraction** | $0 | `CosineStrategy` — semantic clustering |
|
|
392
|
+
| **LLM Extraction** | $$ | `LLMExtractionStrategy` — unstructured content |
|
|
393
|
+
| **Vision Extraction** | $$$ | Screenshot analysis via LLM |
|
|
394
|
+
| **Deep Crawl** | Varies | `AdaptiveCrawler` — full site crawl |
|
|
395
|
+
| **Batch** | Varies | `arun_many()` — parallel multi-URL |
|
|
396
|
+
| **Scroll / Load-More** | $0 | Infinite scroll / AJAX load-more |
|
|
397
|
+
| **Table / PDF / Video** | $0 | Specialized pipelines |
|
|
398
|
+
| **Chunked LLM** | $$ | 3 chunking strategies (regex, sliding, overlapping) |
|
|
399
|
+
|
|
400
|
+
</details>
|
|
401
|
+
|
|
402
|
+
<details>
|
|
403
|
+
<summary><strong>📖 Queen Reader — Content-First Fast Extraction</strong></summary>
|
|
404
|
+
|
|
405
|
+
Inspired by PixelRAG's approach. Navigates with `wait_until='domcontentloaded'` (not `networkidle`) — returns text content **before** the full page loads. No schema generation, no LLM cascade, no waiting for JS/images. Falls back to full load if content < 500 chars.
|
|
406
|
+
|
|
407
|
+
</details>
|
|
408
|
+
|
|
409
|
+
<details>
|
|
410
|
+
<summary><strong>🔢 DOM Serializer & Element Highlighter</strong></summary>
|
|
411
|
+
|
|
412
|
+
browser-use style indexed interactive element mapping. Runs JS to find ALL interactive DOM elements, assigns stable **1-based indices**, builds `selector_map {index → backendNodeId}` for CDP dispatch. The Element Highlighter draws numbered blue outline boxes on each element so the LLM can reference `click(index=N)` or `input(index=N, text="...")`.
|
|
413
|
+
|
|
414
|
+
</details>
|
|
415
|
+
|
|
416
|
+
<details>
|
|
417
|
+
<summary><strong>🔐 Login & Credential Management</strong></summary>
|
|
418
|
+
|
|
419
|
+
Persisted browser profiles, encrypted credential vault, a11y snapshot form filling (works on React/Vue/Angular), multi-strategy login pipeline with wrong-credential retry. Dedicated `LOGIN` + `RECOVER_FROM_BLOCK` action handlers.
|
|
420
|
+
|
|
421
|
+
</details>
|
|
422
|
+
|
|
423
|
+
<details>
|
|
424
|
+
<summary><strong>⚡ Token Budget-Aware LLM Tiering</strong></summary>
|
|
425
|
+
|
|
426
|
+
BrowseMind automatically selects the optimal LLM tier based on your remaining **prompt token budget**:
|
|
427
|
+
|
|
428
|
+
| Tier | Budget | Behavior | Model |
|
|
429
|
+
|------|--------|----------|-------|
|
|
430
|
+
| **🟢 RULE** | < 500 tokens | Zero-LLM — rule-based fallback only | No LLM call |
|
|
431
|
+
| **🟡 CHEAP** | 500–2,000 tokens | Low-cost LLM for simple decisions | `deepseek/deepseek-chat` (or configured cheap provider) |
|
|
432
|
+
| **🔴 FULL** | > 2,000 tokens | Full LLM for complex reasoning | Primary model (DeepSeek/GPT-4/Claude) |
|
|
433
|
+
|
|
434
|
+
Thresholds are configurable in `browsemind.yml`:
|
|
435
|
+
|
|
436
|
+
```yaml
|
|
437
|
+
llm:
|
|
438
|
+
cheap_threshold: 500 # Below this → RULE tier
|
|
439
|
+
full_threshold: 2000 # Above this → FULL tier
|
|
440
|
+
cheap_provider: "deepseek/deepseek-chat" # $0.14/$0.28 per 1M tokens
|
|
441
|
+
```
|
|
442
|
+
|
|
443
|
+
**The stack:**
|
|
444
|
+
- **TokenTracker** — Tracks prompt/completion tokens and total cost per session
|
|
445
|
+
- **LLMTierSelector** — Picks RULE/CHEAP/FULL based on remaining budget
|
|
446
|
+
- **TokenOptimizer** — 14-pattern RuleActionSuggester, FTS5LinkMatcher, BM25Ranker (~80% prompt reduction)
|
|
447
|
+
- **ThresholdSupervisor** — Prevents budget overshoot
|
|
448
|
+
- **Chain failure recovery** — Auto-cascade to next strategy on failure
|
|
449
|
+
|
|
450
|
+
</details>
|
|
451
|
+
|
|
452
|
+
<details>
|
|
453
|
+
<summary><strong>🔌 Plugin System</strong></summary>
|
|
454
|
+
|
|
455
|
+
Three plugin types extend the agent:
|
|
456
|
+
|
|
457
|
+
- **ToolPlugin** — Add new tools to ToolRegistry (Slack, email, etc.)
|
|
458
|
+
- **SkillPlugin** — Prompt-level skills (constraints, context injection)
|
|
459
|
+
- **MCPPlugin** — Wrap MCP servers as agent tools (filesystem, GitHub)
|
|
460
|
+
|
|
461
|
+
</details>
|
|
462
|
+
|
|
463
|
+
<details>
|
|
464
|
+
<summary><strong>🧰 38 Built-in Tool Wrappers</strong></summary>
|
|
465
|
+
|
|
466
|
+
Discoverable tools via ToolRegistry with structured metadata, parameter validation, and failure/success pattern documentation for LLM use. Includes QueenReaderTool, DOMSerializerTool, ElementHighlighterTool.
|
|
467
|
+
|
|
468
|
+
</details>
|
|
469
|
+
|
|
470
|
+
<details>
|
|
471
|
+
<summary><strong>📦 28 Handler Files, 48 Handlers, 141 ActionTypes</strong></summary>
|
|
472
|
+
|
|
473
|
+
Single `ActionDispatcher` routes all 141 action types through 48 specialized handler classes — no if/elif chains.
|
|
474
|
+
|
|
475
|
+
</details>
|
|
476
|
+
|
|
477
|
+
<details>
|
|
478
|
+
<summary><strong>🔎 4 Search Engine Support</strong></summary>
|
|
479
|
+
|
|
480
|
+
Google (CSE API + browser fallback, sign-in redirect fixed), Bing, Brave, DuckDuckGo — auto-fallback orchestration.
|
|
481
|
+
|
|
482
|
+
</details>
|
|
483
|
+
|
|
484
|
+
<details>
|
|
485
|
+
<summary><strong>🧪 JS Browser-Level Test Suite</strong></summary>
|
|
486
|
+
|
|
487
|
+
19 Playwright-based tests in `tests_js/` covering DOM serializer, element highlighter, form interaction, consent manager, human-like behavior, recovery engine, strategy pipeline, tile capture.
|
|
488
|
+
|
|
489
|
+
</details>
|
|
490
|
+
|
|
491
|
+
---
|
|
492
|
+
|
|
493
|
+
## Architecture
|
|
494
|
+
|
|
495
|
+
### Core Loop
|
|
496
|
+
|
|
497
|
+
```
|
|
498
|
+
User Prompt → Entry (CLI/API)
|
|
499
|
+
→ AgentLoop.run()
|
|
500
|
+
→ PageState.capture() # OBSERVE
|
|
501
|
+
→ AgentBrain.assess_progress() # THINK
|
|
502
|
+
→ AgentBrain.decide() # DECIDE (LLM)
|
|
503
|
+
→ ActionDispatcher.dispatch() # ACT
|
|
504
|
+
→ Specific Handler → BrowserAgent
|
|
505
|
+
→ AgentBrain.verify() # VERIFY
|
|
506
|
+
→ Loop until DONE
|
|
507
|
+
```
|
|
508
|
+
|
|
509
|
+
### Architecture Diagram (Mermaid)
|
|
510
|
+
|
|
511
|
+
See [`docs/architecture.mmd`](docs/architecture.mmd) for the full interactive diagram. Key layers:
|
|
512
|
+
|
|
513
|
+
| Layer | Description | Key Files |
|
|
514
|
+
|-------|-------------|-----------|
|
|
515
|
+
| **1. Entry** | CLI + FastAPI | `main.py`, `run_api.py`, `lib/cli/` |
|
|
516
|
+
| **2. Agent Loop & Brain** | Observe→Think→Decide→Act→Verify | `agent_loop.py`, `agent_brain.py`, `page_state.py` |
|
|
517
|
+
| **3. Tool Registry** | 38 AgentTool wrappers + Plugin System | `tools/tool_registry.py`, `tools/builtin_tools.py` |
|
|
518
|
+
| **4. Action Dispatch** | Single dispatch authority | `handlers/__init__.py` |
|
|
519
|
+
| **5. Handler Layer** | 48 handlers across 28 files | `handlers/interaction.py`, `handlers/extraction.py`, ... |
|
|
520
|
+
| **6. Browser Layer** | Unified API (50+ methods) | `browser_agent.py`, `navigator.py` |
|
|
521
|
+
| **7. Extraction Layer** | 18 pipelines, cost-ascending cascade | `strategy_pipeline.py`, `queen_reader.py` |
|
|
522
|
+
| **8. Content Pipeline** | Queen Reader, DOM Serializer, Highlighter | `queen_reader.py`, `dom_serializer.py`, `element_highlighter.py` |
|
|
523
|
+
| **9. Support & Infrastructure** | Cache, Memory, Proxy, Identity, Telemetry | `cache.py`, `memory/`, `proxy_manager.py`, `identity_manager.py` |
|
|
524
|
+
| **10. Multi-Agent System** | Planner/Verifier/Supervisor (advisory) | `agents/planner.py`, `agents/verifier.py` |
|
|
525
|
+
|
|
526
|
+
### Key Metrics
|
|
527
|
+
|
|
528
|
+
| Metric | Value |
|
|
529
|
+
|--------|-------|
|
|
530
|
+
| Action types | **141** |
|
|
531
|
+
| Handler files | **28** |
|
|
532
|
+
| Concrete handlers | **48** |
|
|
533
|
+
| AgentTool wrappers | **38** |
|
|
534
|
+
| Extraction pipelines | **18** |
|
|
535
|
+
| Search engines | **4** |
|
|
536
|
+
| Cache tiers | **4** (L0–L3) |
|
|
537
|
+
| Memory tiers | **3** (Working/Episodic/Semantic) |
|
|
538
|
+
| Plugin types | **3** (Tool/Skill/MCP) |
|
|
539
|
+
| Largest file | `strategy_pipeline.py` (~4,400 lines) |
|
|
540
|
+
| System prompt | **97 lines / ~959 tokens** |
|
|
541
|
+
| JS test suite | **19 files** in `tests_js/` |
|
|
542
|
+
|
|
543
|
+
### Key Design Principles
|
|
544
|
+
|
|
545
|
+
| Principle | Description |
|
|
546
|
+
|-----------|-------------|
|
|
547
|
+
| **LLM is Primary** | Accuracy over cost — LLM consulted first for every decision |
|
|
548
|
+
| **Rules Suggest** | RuleActionSuggester provides hints, not commands |
|
|
549
|
+
| **Zero-LLM by Default** | Extraction, navigation, link matching use 0 LLM tokens |
|
|
550
|
+
| **Cost-Ascending Cascade** | Identity→CSS→...→LLM→Vision (LLM is absolute LAST) |
|
|
551
|
+
| **No Hardcoded Names** | Element recognition uses HTML semantics + WAI-ARIA |
|
|
552
|
+
| **Structural Overlays** | Consent dialogs detected by `role=dialog`, `position:fixed` |
|
|
553
|
+
|
|
554
|
+
---
|
|
555
|
+
|
|
556
|
+
## 🐍 Python API
|
|
557
|
+
|
|
558
|
+
```python
|
|
559
|
+
import asyncio
|
|
560
|
+
from lib.agent_loop import AgentLoop
|
|
561
|
+
from lib.config import AppConfig
|
|
562
|
+
|
|
563
|
+
async def main():
|
|
564
|
+
config = AppConfig.load("browsemind.yml")
|
|
565
|
+
loop = AgentLoop(config)
|
|
566
|
+
result = await loop.run("Navigate to example.com and extract all headings")
|
|
567
|
+
print(f"Success: {result.success}")
|
|
568
|
+
print(f"Steps: {result.steps_taken}")
|
|
569
|
+
print(f"Data: {result.data}")
|
|
570
|
+
print(f"Cost: ${result.total_cost:.4f}")
|
|
571
|
+
|
|
572
|
+
asyncio.run(main())
|
|
573
|
+
```
|
|
574
|
+
|
|
575
|
+
### Programmatic Extraction
|
|
576
|
+
|
|
577
|
+
```python
|
|
578
|
+
from lib.strategy_pipeline import StrategyPipeline
|
|
579
|
+
from lib.crawl4ai_config import Crawl4AIConfigBuilder
|
|
580
|
+
|
|
581
|
+
config = (
|
|
582
|
+
Crawl4AIConfigBuilder()
|
|
583
|
+
.with_css_selector(".product")
|
|
584
|
+
.with_word_count_threshold(50)
|
|
585
|
+
.with_cache_mode("BYPASS")
|
|
586
|
+
.build()
|
|
587
|
+
)
|
|
588
|
+
|
|
589
|
+
pipeline = StrategyPipeline(crawler)
|
|
590
|
+
result = await pipeline.run(
|
|
591
|
+
url="https://books.toscrape.com",
|
|
592
|
+
strategy="css",
|
|
593
|
+
schema={
|
|
594
|
+
"baseSelector": ".product",
|
|
595
|
+
"fields": [
|
|
596
|
+
{"name": "title", "selector": "h3 a", "type": "text"},
|
|
597
|
+
{"name": "price", "selector": ".price", "type": "text"},
|
|
598
|
+
]
|
|
599
|
+
}
|
|
600
|
+
)
|
|
601
|
+
print(result.extracted[:5])
|
|
602
|
+
```
|
|
603
|
+
|
|
604
|
+
---
|
|
605
|
+
|
|
606
|
+
## 🔧 Configuration
|
|
607
|
+
|
|
608
|
+
### LLM Providers (YAML-Driven)
|
|
609
|
+
|
|
610
|
+
Configuration lives in a single file: [`browsemind.yml`](browsemind.yml). API keys go in `llm.env` (git-ignored).
|
|
611
|
+
|
|
612
|
+
```yaml
|
|
613
|
+
llm:
|
|
614
|
+
default_provider: "deepseek/deepseek-chat"
|
|
615
|
+
extraction_provider: "deepseek/deepseek-chat"
|
|
616
|
+
config:
|
|
617
|
+
temperature: 0.3
|
|
618
|
+
max_tokens: 4096
|
|
619
|
+
```
|
|
620
|
+
|
|
621
|
+
**llm.env:**
|
|
622
|
+
|
|
623
|
+
```env
|
|
624
|
+
DEEPSEEK_API_KEY=sk-your-deepseek-key
|
|
625
|
+
# OPENAI_API_KEY=sk-your-openai-key
|
|
626
|
+
# GROQ_API_KEY=gsk-your-groq-key
|
|
627
|
+
# ANTHROPIC_API_KEY=sk-ant-your-anthropic-key
|
|
628
|
+
```
|
|
629
|
+
|
|
630
|
+
Supported providers (any LiteLLM-compatible):
|
|
631
|
+
|
|
632
|
+
- `deepseek/deepseek-chat` — **default** ($0.14/$0.28 per 1M tokens, cheapest June 2026)
|
|
633
|
+
- `deepseek/deepseek-v4-pro` — Premium tier ($0.435/$0.87 per 1M tokens)
|
|
634
|
+
- `openai/gpt-4o-mini`, `openai/gpt-4o`
|
|
635
|
+
- `groq/meta-llama/llama-4-scout-17b-16e-instruct`
|
|
636
|
+
- `anthropic/claude-3-haiku`, `anthropic/claude-3-opus`
|
|
637
|
+
- Any OpenAI-compatible endpoint
|
|
638
|
+
|
|
639
|
+
### Extraction Configuration
|
|
640
|
+
|
|
641
|
+
18 LLM-configurable parameters via `ExtractionConfig`:
|
|
642
|
+
|
|
643
|
+
| Parameter | Type | Description |
|
|
644
|
+
|-----------|------|-------------|
|
|
645
|
+
| `wait_for` | `str` | CSS/JS condition before extraction |
|
|
646
|
+
| `scan_full_page` | `bool` | Auto-scroll for infinite content |
|
|
647
|
+
| `word_count_threshold` | `int` | Min words per block (default: 200) |
|
|
648
|
+
| `css_selector` | `str` | Focus on specific page section |
|
|
649
|
+
| `excluded_tags` | `list` | Remove specific HTML tags |
|
|
650
|
+
| `remove_overlay_elements` | `bool` | Remove popups/modals |
|
|
651
|
+
| `simulate_user` | `bool` | Simulate mouse movements |
|
|
652
|
+
| `magic` | `bool` | Auto-handle popups/consent |
|
|
653
|
+
| `cache_mode` | `str` | `ENABLED/BYPASS/DISABLED/READ_ONLY/WRITE_ONLY` |
|
|
654
|
+
| `process_iframes` | `bool` | Inline iframe content |
|
|
655
|
+
| `flatten_shadow_dom` | `bool` | Flatten Shadow DOM |
|
|
656
|
+
|
|
657
|
+
---
|
|
658
|
+
|
|
659
|
+
## 🔬 Testing
|
|
660
|
+
|
|
661
|
+
### Python Tests
|
|
662
|
+
|
|
663
|
+
```bash
|
|
664
|
+
# Run all unit tests
|
|
665
|
+
pytest
|
|
666
|
+
|
|
667
|
+
# Run specific test file
|
|
668
|
+
pytest tests/test_improvements.py -v
|
|
669
|
+
|
|
670
|
+
# Run with coverage
|
|
671
|
+
pytest --cov=lib tests/
|
|
672
|
+
```
|
|
673
|
+
|
|
674
|
+
### JS Browser-Level Tests (19 Playwright tests)
|
|
675
|
+
|
|
676
|
+
```bash
|
|
677
|
+
cd tests_js
|
|
678
|
+
node run_all.js
|
|
679
|
+
```
|
|
680
|
+
|
|
681
|
+
Individual test files in `tests_js/`:
|
|
682
|
+
|
|
683
|
+
- `test_dom_serializer.js` — Element indexing and selector maps
|
|
684
|
+
- `test_element_highlighter.js` — Numbered overlay rendering
|
|
685
|
+
- `test_consent_manager.js` — Consent dismissal with overlay detection
|
|
686
|
+
- `test_form_interaction.js` — Form fill and submit flows
|
|
687
|
+
- `test_human_like_behavior.js` — Human-like behavior simulation
|
|
688
|
+
- `test_tile_capture.js` — Tile-based screenshot capture
|
|
689
|
+
- `test_strategy_pipeline.js` — Pipeline cascade behavior
|
|
690
|
+
- `test_recovery_engine.js` — Recovery strategy behavior
|
|
691
|
+
|
|
692
|
+
### CDP & Navigation Diagnostics
|
|
693
|
+
|
|
694
|
+
```bash
|
|
695
|
+
python tests/test_diagnose_cdp.py
|
|
696
|
+
python tests/test_diagnose_navigation.py
|
|
697
|
+
```
|
|
698
|
+
|
|
699
|
+
---
|
|
700
|
+
|
|
701
|
+
## 📁 Project Structure
|
|
702
|
+
|
|
703
|
+
```
|
|
704
|
+
browsemind/
|
|
705
|
+
├── main.py # CLI entry (task mode + command mode)
|
|
706
|
+
├── run_api.py # FastAPI server entry
|
|
707
|
+
├── pyproject.toml # Project config + dependencies
|
|
708
|
+
├── browsemind.yml # YAML-driven configuration
|
|
709
|
+
├── llm.env / llm.env.example # API keys (git-ignored)
|
|
710
|
+
│
|
|
711
|
+
├── lib/ # Core library
|
|
712
|
+
│ ├── agent_loop.py # Core iteration loop
|
|
713
|
+
│ ├── agent_brain.py # LLM decision engine (~1,771 lines)
|
|
714
|
+
│ ├── page_state.py # DOM observation (~620 lines)
|
|
715
|
+
│ ├── actions.py # 141 ActionTypes + dataclasses
|
|
716
|
+
│ ├── browser_agent.py # Unified browser API (~1,750 lines)
|
|
717
|
+
│ ├── strategy_pipeline.py # Single extraction authority (~4,400 lines)
|
|
718
|
+
│ ├── queen_reader.py # DOMContentLoaded fast path
|
|
719
|
+
│ ├── dom_serializer.py # browser-use style indexed elements
|
|
720
|
+
│ ├── element_highlighter.py # Numbered blue overlays
|
|
721
|
+
│ ├── navigator.py # Anti-bot strategy chain
|
|
722
|
+
│ ├── human_like_behavior.py # Mouse/keyboard emulation
|
|
723
|
+
│ ├── consent_manager.py # Overlay/modal removal
|
|
724
|
+
│ ├── login_pipeline.py # Automated login flows
|
|
725
|
+
│ │
|
|
726
|
+
│ ├── handlers/ # 28 files, 48 handlers, 141 action types
|
|
727
|
+
│ │ ├── interaction.py # Click, Input, Scroll, Hover, DblClick, Drag, Upload
|
|
728
|
+
│ │ ├── extraction.py # 11 extraction action types
|
|
729
|
+
│ │ ├── navigation.py # Navigate, session/proxy navigate
|
|
730
|
+
│ │ ├── download.py # Download, DownloadMany (yt-dlp)
|
|
731
|
+
│ │ ├── search_site.py # Intra-site page discovery
|
|
732
|
+
│ │ ├── tabs.py # Multi-tab + page history operations
|
|
733
|
+
│ │ └── ... # 22 more handler files
|
|
734
|
+
│ │
|
|
735
|
+
│ ├── tools/ # Tool Registry + SERP integrations
|
|
736
|
+
│ │ ├── tool_registry.py # Central registry
|
|
737
|
+
│ │ ├── builtin_tools.py # 38 AgentTool wrappers
|
|
738
|
+
│ │ ├── google_serp.py # Google search (CSE + browser)
|
|
739
|
+
│ │ ├── bing_serp.py # Bing search
|
|
740
|
+
│ │ ├── brave_serp.py # Brave search
|
|
741
|
+
│ │ └── duckduckgo_serp.py # DuckDuckGo search
|
|
742
|
+
│ │
|
|
743
|
+
│ ├── memory/ # 3-tier memory (SQLite-backed)
|
|
744
|
+
│ │ ├── working.py # Current session actions
|
|
745
|
+
│ │ ├── episodic.py # Past sessions
|
|
746
|
+
│ │ └── semantic.py # Cross-session patterns + FTS5
|
|
747
|
+
│ │
|
|
748
|
+
│ ├── agents/ # Multi-agent system (advisory)
|
|
749
|
+
│ │ ├── planner.py # Task decomposition
|
|
750
|
+
│ │ ├── verifier.py # Outcome verification
|
|
751
|
+
│ │ └── supervisor.py # Task supervision
|
|
752
|
+
│ │
|
|
753
|
+
│ ├── plugin/ # Plugin system
|
|
754
|
+
│ │ ├── base.py # Plugin ABCs
|
|
755
|
+
│ │ ├── plugin_manager.py # Lifecycle management
|
|
756
|
+
│ │ └── mcp_plugin.py # MCP server integration
|
|
757
|
+
│ │
|
|
758
|
+
│ ├── api/ # FastAPI REST
|
|
759
|
+
│ │ └── routes.py # 8 endpoints
|
|
760
|
+
│ │
|
|
761
|
+
│ └── cli/ # Unified CLI
|
|
762
|
+
│ ├── args.py # Argument parser
|
|
763
|
+
│ └── crwl_cli.py # Command implementations
|
|
764
|
+
│
|
|
765
|
+
├── archive/plans/ # Archived design documents
|
|
766
|
+
├── docs/ # Documentation
|
|
767
|
+
│ ├── architecture.mmd # Mermaid diagram
|
|
768
|
+
│ ├── DYNAMIC_DATA_EXTRACTION_GUIDE.md # 52 workflow states
|
|
769
|
+
│ └── ... # Crawl4AI docs cache
|
|
770
|
+
│
|
|
771
|
+
├── tests/ # Python test suite
|
|
772
|
+
├── tests_js/ # 19 Playwright-based browser tests
|
|
773
|
+
├── tutorial/ # Crawl4AI tutorial scripts
|
|
774
|
+
└── output/ # Agent output directory
|
|
775
|
+
```
|
|
776
|
+
|
|
777
|
+
---
|
|
778
|
+
|
|
779
|
+
## 🤝 Contributing
|
|
780
|
+
|
|
781
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md) for detailed guidelines.
|
|
782
|
+
|
|
783
|
+
**Quick start:**
|
|
784
|
+
|
|
785
|
+
```bash
|
|
786
|
+
git clone https://github.com/prokopis3/browsemind.git
|
|
787
|
+
cd browsemind
|
|
788
|
+
python -m venv .venv && source .venv/bin/activate
|
|
789
|
+
pip install -e ".[dev]"
|
|
790
|
+
playwright install chromium
|
|
791
|
+
```
|
|
792
|
+
|
|
793
|
+
**Commit conventions:** We follow [Conventional Commits](https://www.conventionalcommits.org/) with SemVer. See [commitlint.config.js](commitlint.config.js) for allowed scopes and types.
|
|
794
|
+
|
|
795
|
+
**Code of Conduct:** [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md)
|
|
796
|
+
|
|
797
|
+
---
|
|
798
|
+
|
|
799
|
+
## 📚 Documentation
|
|
800
|
+
|
|
801
|
+
| Resource | Description |
|
|
802
|
+
|----------|-------------|
|
|
803
|
+
| [Architecture Deep Dive](ARCHITECTURE_DEEP_DIVE.md) | Comprehensive 16-section architecture analysis |
|
|
804
|
+
| [Roadmap](ROADMAP.md) | Future priorities, milestones, and research areas |
|
|
805
|
+
| [Changelog](CHANGELOG.md) | Full release history with categorized entries |
|
|
806
|
+
| [Architecture Diagram](docs/architecture.mmd) | Interactive Mermaid architecture diagram |
|
|
807
|
+
| [Dynamic Data Extraction Guide](docs/DYNAMIC_DATA_EXTRACTION_GUIDE.md) | 52 workflow state patterns for LLM agents |
|
|
808
|
+
| [Crawl4AI API Reference](docs/CRAWL4AI_ARCHITECTURE_REFERENCE.md) | Complete crawl4ai API surface reference |
|
|
809
|
+
| [Plugin Architecture](lib/plugin/ARCHITECTURE.md) | Plugin system design and lifecycle |
|
|
810
|
+
| [Configuration File](browsemind.yml) | YAML configuration reference |
|
|
811
|
+
| [Contributing Guidelines](CONTRIBUTING.md) | How to contribute to the project |
|
|
812
|
+
| [Security Policy](SECURITY.md) | Guidelines for reporting vulnerabilities |
|
|
813
|
+
| [Code of Conduct](CODE_OF_CONDUCT.md) | Community standards and expectations |
|
|
814
|
+
|
|
815
|
+
---
|
|
816
|
+
|
|
817
|
+
## 🙏 Acknowledgments
|
|
818
|
+
|
|
819
|
+
- **[Crawl4AI](https://github.com/unclecode/crawl4ai)** — The foundation web crawling library
|
|
820
|
+
- **[Browser-Use](https://github.com/browser-use/browser-use)** — Inspiration for DOM interaction patterns and CLI design
|
|
821
|
+
- **[Page-Agent](https://github.com/alibaba/page-agent)** — Inspiration for interactive element detection and indexing
|
|
822
|
+
- **[PixelRAG](https://github.com/StarTrail-org/PixelRAG)** — Inspiration for Queen Reader fast extraction and tile-based capture
|
|
823
|
+
- **[LiteLLM](https://github.com/BerriAI/litellm)** — Multi-provider LLM interface
|
|
824
|
+
- **[Playwright](https://playwright.dev/)** — Browser automation engine
|
|
825
|
+
|
|
826
|
+
---
|
|
827
|
+
|
|
828
|
+
## ⚖️ License
|
|
829
|
+
|
|
830
|
+
Copyright (c) 2026 BrowseMind Contributors. Licensed under the **GNU AGPL v3** — see [LICENSE](LICENSE) for details.
|
|
831
|
+
|
|
832
|
+
---
|
|
833
|
+
|
|
834
|
+
## Disclaimer
|
|
835
|
+
|
|
836
|
+
> [!CAUTION]
|
|
837
|
+
>
|
|
838
|
+
> This library is provided for **educational and research purposes only**. By using this library, you agree to comply with local and international data scraping and privacy laws. The authors and contributors are not responsible for any misuse of this software. Always respect the terms of service of websites and `robots.txt` files.
|
|
839
|
+
|
|
840
|
+
---
|
|
841
|
+
|
|
842
|
+
## 🎓 Citations
|
|
843
|
+
|
|
844
|
+
If you have used this library for research purposes, please cite us with the following references:
|
|
845
|
+
|
|
846
|
+
### BrowseMind
|
|
847
|
+
|
|
848
|
+
**BibTeX:**
|
|
849
|
+
```bibtex
|
|
850
|
+
@misc{browsemind,
|
|
851
|
+
author = {Prokopis3},
|
|
852
|
+
title = {BrowseMind: LLM Browser Automation Agent},
|
|
853
|
+
year = {2026},
|
|
854
|
+
publisher = {GitHub},
|
|
855
|
+
journal = {GitHub Repository},
|
|
856
|
+
url = {https://github.com/prokopis3/browsemind},
|
|
857
|
+
note = {An LLM browser automation \& web scraping agent powered by Crawl4AI}
|
|
858
|
+
}
|
|
859
|
+
```
|
|
860
|
+
|
|
861
|
+
**Text citation:**
|
|
862
|
+
> Prokopis3 (2026). *BrowseMind: LLM Browser Automation Agent* [Computer software]. GitHub. https://github.com/prokopis3/browsemind
|
|
863
|
+
|
|
864
|
+
### Crawl4AI (underlying engine)
|
|
865
|
+
|
|
866
|
+
**BibTeX:**
|
|
867
|
+
```bibtex
|
|
868
|
+
@software{crawl4ai2024,
|
|
869
|
+
author = {UncleCode},
|
|
870
|
+
title = {Crawl4AI: Open-source LLM Friendly Web Crawler \& Scraper},
|
|
871
|
+
year = {2024},
|
|
872
|
+
publisher = {GitHub},
|
|
873
|
+
journal = {GitHub Repository},
|
|
874
|
+
howpublished = {\url{https://github.com/unclecode/crawl4ai}},
|
|
875
|
+
commit = {c66f3276fd355031c8632500911fe7041ad6fc14}
|
|
876
|
+
}
|
|
877
|
+
```
|
|
878
|
+
|
|
879
|
+
---
|
|
880
|
+
|
|
881
|
+
## ☕ Support
|
|
882
|
+
|
|
883
|
+
If you find this project useful, consider buying me a coffee!
|
|
884
|
+
|
|
885
|
+
<div align="center">
|
|
886
|
+
|
|
887
|
+
|
|
888
|
+
|
|
889
|
+
<a href="https://www.buymeacoffee.com/prokopis" target="_blank"><img src="https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png" alt="Buy Me a Coffee" style="height: 60px !important;width: 217px !important;" ></a>
|
|
890
|
+
<br><br>
|
|
891
|
+
|
|
892
|
+
<a href="https://giphy.com/stickers/buy-me-a-coffee-support-thanks-for-your-hXMGQqJFlIQMOjpsKC" target="_blank">
|
|
893
|
+
<img src="https://media1.giphy.com/media/v1.Y2lkPTc5MGI3NjExcWZpdGpuc2dkZjZoMmRoanRzNnhhcGtqcGl6eTU0dWcwd2dxcGk4MyZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9cw/hXMGQqJFlIQMOjpsKC/giphy.gif" alt="Thank you — your support means a lot!" width="320">
|
|
894
|
+
</a>
|
|
895
|
+
|
|
896
|
+
</div>
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* BrowseMind — Node.js CLI Wrapper
|
|
5
|
+
* ===================================
|
|
6
|
+
* Thin wrapper that spawns the Python CLI. Enables npm/bun distribution
|
|
7
|
+
* while the Python backend handles all actual logic.
|
|
8
|
+
*
|
|
9
|
+
* Usage:
|
|
10
|
+
* browsemind <command> [options]
|
|
11
|
+
* crwl <command> [options]
|
|
12
|
+
*
|
|
13
|
+
* Postinstall:
|
|
14
|
+
* node bin/browsemind.js postinstall — first-time setup
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
const { spawn, execSync } = require("child_process");
|
|
18
|
+
const path = require("path");
|
|
19
|
+
const fs = require("fs");
|
|
20
|
+
|
|
21
|
+
const PACKAGE_NAME = "browsemind";
|
|
22
|
+
const CLI_NAME = "browsemind";
|
|
23
|
+
|
|
24
|
+
function findPython() {
|
|
25
|
+
// Try uv-managed Python first, then system Python
|
|
26
|
+
const candidates = ["uv run python", "python3", "python", "py -3"];
|
|
27
|
+
for (const py of candidates) {
|
|
28
|
+
try {
|
|
29
|
+
const [cmd, ...args] = py.split(" ");
|
|
30
|
+
execSync(`${cmd} ${args.join(" ")} --version`, { stdio: "ignore" });
|
|
31
|
+
return py;
|
|
32
|
+
} catch {
|
|
33
|
+
continue;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return "python";
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function getProjectRoot() {
|
|
40
|
+
// Resolve the package root (where package.json and main.py live)
|
|
41
|
+
let dir = __dirname;
|
|
42
|
+
for (let i = 0; i < 5; i++) {
|
|
43
|
+
dir = path.resolve(dir, "..");
|
|
44
|
+
if (fs.existsSync(path.join(dir, "pyproject.toml"))) {
|
|
45
|
+
return dir;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
// Fallback: assume we're in node_modules/.bin/ or bin/
|
|
49
|
+
return path.resolve(__dirname, "..");
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function runPostinstall() {
|
|
53
|
+
const root = getProjectRoot();
|
|
54
|
+
console.log(`\n 📦 ${PACKAGE_NAME} v${require("../package.json").version}`);
|
|
55
|
+
console.log(` Setting up Python environment...`);
|
|
56
|
+
|
|
57
|
+
const py = findPython();
|
|
58
|
+
const mainPy = path.join(root, "main.py");
|
|
59
|
+
|
|
60
|
+
if (!fs.existsSync(mainPy)) {
|
|
61
|
+
console.error(` ❌ Could not find main.py at ${mainPy}`);
|
|
62
|
+
console.error(` Please install from source: git clone <repo> && cd ${PACKAGE_NAME}`);
|
|
63
|
+
process.exit(1);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// Install Python dependencies
|
|
67
|
+
try {
|
|
68
|
+
console.log(` Installing Python dependencies...`);
|
|
69
|
+
if (py.startsWith("uv")) {
|
|
70
|
+
execSync("uv sync", { cwd: root, stdio: "inherit" });
|
|
71
|
+
} else {
|
|
72
|
+
execSync(`${py} -m pip install -e .`, { cwd: root, stdio: "inherit" });
|
|
73
|
+
}
|
|
74
|
+
} catch (e) {
|
|
75
|
+
console.error(` ⚠️ pip install failed: ${e.message}`);
|
|
76
|
+
console.log(` Run '${py} -m pip install -e .' manually.`);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Install Playwright browsers
|
|
80
|
+
try {
|
|
81
|
+
console.log(` Installing Playwright browser (Chromium)...`);
|
|
82
|
+
execSync(`${py} -m playwright install chromium`, { cwd: root, stdio: "inherit" });
|
|
83
|
+
} catch {
|
|
84
|
+
console.log(` ⚠️ Playwright browser install skipped. Run 'playwright install chromium' if needed.`);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
console.log(`\n ✅ ${PACKAGE_NAME} ready!`);
|
|
88
|
+
console.log(` Run 'browsemind doctor' to verify installation.`);
|
|
89
|
+
console.log(` Run 'browsemind --help' to see available commands.\n`);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function runCLI() {
|
|
93
|
+
const args = process.argv.slice(2);
|
|
94
|
+
const root = getProjectRoot();
|
|
95
|
+
const mainPy = path.join(root, "main.py");
|
|
96
|
+
const py = findPython();
|
|
97
|
+
|
|
98
|
+
if (!fs.existsSync(mainPy)) {
|
|
99
|
+
console.error(`❌ Could not find main.py at ${mainPy}`);
|
|
100
|
+
process.exit(1);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// Build the command based on Python runtime
|
|
104
|
+
let cmd, cmdArgs;
|
|
105
|
+
if (py.startsWith("uv")) {
|
|
106
|
+
cmd = "uv";
|
|
107
|
+
cmdArgs = ["run", "python", mainPy, ...args];
|
|
108
|
+
} else {
|
|
109
|
+
cmd = py;
|
|
110
|
+
cmdArgs = [mainPy, ...args];
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const proc = spawn(cmd, cmdArgs, {
|
|
114
|
+
stdio: "inherit",
|
|
115
|
+
cwd: root,
|
|
116
|
+
env: { ...process.env, PYTHONUNBUFFERED: "1" },
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
proc.on("close", (code) => {
|
|
120
|
+
process.exit(code ?? 0);
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
proc.on("error", (err) => {
|
|
124
|
+
console.error(`❌ Failed to start: ${err.message}`);
|
|
125
|
+
process.exit(1);
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// ── Entry ─────────────────────────────────────────────────────────────
|
|
130
|
+
|
|
131
|
+
if (process.argv[2] === "postinstall") {
|
|
132
|
+
runPostinstall();
|
|
133
|
+
} else {
|
|
134
|
+
runCLI();
|
|
135
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "browsemind",
|
|
3
|
+
"version": "0.5.0",
|
|
4
|
+
"description": "LLM browser automation agent — crawl, navigate, extract, interact",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"browser-automation",
|
|
7
|
+
"web-scraping",
|
|
8
|
+
"crawling",
|
|
9
|
+
"ai-agent",
|
|
10
|
+
"llm",
|
|
11
|
+
"crawl4ai",
|
|
12
|
+
"web-crawler"
|
|
13
|
+
],
|
|
14
|
+
"homepage": "https://github.com/prokopis3/browsemind",
|
|
15
|
+
"repository": {
|
|
16
|
+
"type": "git",
|
|
17
|
+
"url": "git+https://github.com/prokopis3/browsemind.git"
|
|
18
|
+
},
|
|
19
|
+
"license": "AGPL-3.0-or-later",
|
|
20
|
+
"author": "BrowseMind Contributors",
|
|
21
|
+
"bin": {
|
|
22
|
+
"browsemind": "./bin/browsemind.js"
|
|
23
|
+
},
|
|
24
|
+
"files": [
|
|
25
|
+
"bin/",
|
|
26
|
+
"README.md",
|
|
27
|
+
"LICENSE"
|
|
28
|
+
],
|
|
29
|
+
"engines": {
|
|
30
|
+
"node": ">=18.0.0"
|
|
31
|
+
},
|
|
32
|
+
"preferGlobal": true,
|
|
33
|
+
"scripts": {
|
|
34
|
+
"postinstall": "node bin/browsemind.js postinstall",
|
|
35
|
+
"postupdate": "node bin/browsemind.js postinstall",
|
|
36
|
+
"prepare": "husky"
|
|
37
|
+
},
|
|
38
|
+
"lint-staged": {
|
|
39
|
+
"*.{py,pyw}": [
|
|
40
|
+
"uv tool run ruff check --fix --unsafe-fixes",
|
|
41
|
+
"uv tool run ruff format"
|
|
42
|
+
],
|
|
43
|
+
"*.{yml,yaml,json,md}": [
|
|
44
|
+
"npx --no prettier --write"
|
|
45
|
+
]
|
|
46
|
+
},
|
|
47
|
+
"devDependencies": {
|
|
48
|
+
"@commitlint/cli": "^21.1.0",
|
|
49
|
+
"@commitlint/config-conventional": "^21.1.0",
|
|
50
|
+
"husky": "^9.1.7",
|
|
51
|
+
"lint-staged": "^17.0.8",
|
|
52
|
+
"prettier": "^3.9.3"
|
|
53
|
+
}
|
|
54
|
+
}
|