@bacnh85/pi-web 0.2.1 → 0.4.1

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 CHANGED
@@ -1,31 +1,23 @@
1
- # pi-web
1
+ # pi-web v0.4
2
2
 
3
- Pi extension for web search, readable page extraction, and Firecrawl scraping/crawling.
3
+ Pi extension for **unified web search, content extraction, site crawling, and page capture**.
4
4
 
5
- ## Install
5
+ Auto-selects the best backend from SearXNG (self-hosted), Brave Search, Firecrawl, and Crawl4AI — so agents don't have to know which backend to use. Search selection is adaptive: broad discovery prefers self-hosted SearXNG, while precision-sensitive searches and inline content prefer Brave.
6
6
 
7
- Install the published package from npm:
7
+ ## Install
8
8
 
9
9
  ```bash
10
10
  pi install npm:@bacnh85/pi-web
11
11
  ```
12
12
 
13
- From this repository checkout, install only this extension package:
13
+ From this repository:
14
14
 
15
15
  ```bash
16
- cd extensions/pi-web
17
- npm install
18
- cd ../..
19
-
20
16
  pi install ./extensions/pi-web
21
17
  # or test directly
22
18
  pi -e ./extensions/pi-web
23
19
  ```
24
20
 
25
- The package manifest points Pi directly at `./index.ts`, so published npm installs and local installs load the same extension entrypoint.
26
-
27
- If you manually copy this directory instead of using `pi install`, run `npm install --omit=dev` in the copied `pi-web` directory so readable-content dependencies such as `@mozilla/readability` are present.
28
-
29
21
  ## Configuration
30
22
 
31
23
  Environment lookup order:
@@ -33,66 +25,198 @@ Environment lookup order:
33
25
  1. Process environment
34
26
  2. Current working directory `.env.local`
35
27
  3. Current working directory `.env`
36
- 4. Pi global config `.env.local` (`$PI_CODING_AGENT_DIR/.env.local` when set; otherwise `~/.pi/agent/.env.local`)
37
- 5. Pi global config `.env` (`$PI_CODING_AGENT_DIR/.env` when set; otherwise `~/.pi/agent/.env`)
28
+ 4. Pi global config `~/.pi/agent/.env.local`
29
+ 5. Pi global config `~/.pi/agent/.env`
38
30
 
39
31
  Variables:
40
32
 
41
- - `BRAVE_API_KEY` required for Brave Search.
42
- - `SEARXNG_BASE_URL` — optional; defaults to `http://172.30.55.22:8888`.
43
- - `FIRECRAWL_API_URL` — optional; defaults to `https://api.firecrawl.dev/v2`.
44
- - `FIRECRAWL_API_KEY` required for hosted Firecrawl, optional for self-hosted instances without auth.
45
- - `FIRECRAWL_TIMEOUT_MS` optional request timeout, default `60000`.
33
+ | Variable | Required | Default | Notes |
34
+ |---|---|---|---|
35
+ | `BRAVE_API_KEY` | No (1) | | Brave Search API key |
36
+ | `SEARXNG_BASE_URL` | No | `http://172.30.55.22:8888` | Self-hosted SearXNG |
37
+ | `FIRECRAWL_API_URL` | No | `https://api.firecrawl.dev/v2` | Self-hosted or hosted |
38
+ | `FIRECRAWL_API_KEY` | No (2) | — | Required for hosted Firecrawl |
39
+ | `CRAWL4AI_API_URL` | No | `http://172.30.55.22:11235` | Self-hosted Crawl4AI |
40
+ | `CRAWL4AI_API_TOKEN` | No (3) | — | Required if Crawl4AI auth enabled |
41
+
42
+ > (1) At least one search backend (SearXNG, Brave, or Firecrawl) must be configured for `web_search`.
43
+ > (2) Required for hosted Firecrawl; optional for self-hosted instances without auth.
44
+ > (3) Required for Crawl4AI v0.9+ default config.
46
45
 
47
- Secrets are never printed; status reports only show presence/source.
46
+ Secrets are never printed; `web_status` reports only presence/source.
48
47
 
49
48
  ## Tools
50
49
 
51
- Brave:
50
+ ### `web_search` — Unified search
51
+
52
+ Searches the web. Auto-selects backends adaptively: SearXNG for broad self-hosted discovery, Brave for precision-sensitive queries and `include_content`, Firecrawl as last resort.
52
53
 
53
- - `brave_search` — search web results, optionally fetch readable result content.
54
+ ```
55
+ web_search query="ansible podman quadlet" count=5
56
+ web_search query="ansible documentation" backend=brave count=10
57
+ web_search query="latest python release" engines="google,github"
58
+ web_search query="riven media" include_content=true
59
+ ```
54
60
 
55
- Web Content:
61
+ Parameters:
56
62
 
57
- - `web_content` fetch a URL and extract readable markdown (formerly `brave_content`; renamed in v0.2.0 because it does not use the Brave API).
63
+ | Parameter | Type | Default | Description |
64
+ |---|---|---|---|
65
+ | `query` | string | — | Search query |
66
+ | `count` | number | 5 | Number of results (max 20) |
67
+ | `freshness` | string | — | Time filter: `pw`, `pm`, `py`, or `YYYY-MM-DDtoYYYY-MM-DD` |
68
+ | `country` | string | `US` | Two-letter country code |
69
+ | `backend` | string | `auto` | Force backend: `auto`, `searxng`, `brave`, `firecrawl` |
70
+ | `engines` | string | — | SearXNG engine override, e.g. `google,github` |
71
+ | `include_content` | boolean | false | Fetch page content alongside results |
72
+ | `content_chars` | number | 5000 | Max content chars per result |
58
73
 
59
- SearXNG:
74
+ **Auto-selection behavior:**
60
75
 
61
- - `searxng_search`search web results through a configured self-hosted SearXNG metasearch instance.
76
+ 1. **SearXNG**first for broad/general discovery, especially when `engines` is supplied.
77
+ 2. **Brave** — first for precision-sensitive queries (`site:`, quoted phrases, docs/API/source lookups, short proper-name queries) and whenever `include_content` is true. Requires `BRAVE_API_KEY`.
78
+ 3. **Firecrawl Search** — last resort. ⚠️ Poor semantic accuracy on domain-specific/ambiguous queries (e.g., "Riven" returns League of Legends results). Prefer SearXNG or Brave for precision.
62
79
 
63
- Firecrawl:
80
+ Tool output includes search diagnostics showing attempted backends and the selected backend.
64
81
 
65
- - `firecrawl_search` search web/news/images, optionally scrape result markdown.
66
- - `firecrawl_scrape` — scrape a URL as markdown/html/links/summary/json.
67
- - `firecrawl_map` — discover URLs for a site.
68
- - `firecrawl_crawl` — start a conservative crawl, optionally polling for results.
82
+ Use `backend` parameter to force a specific backend when needed.
69
83
 
70
- Utility:
84
+ ### `web_extract` — Unified content extraction
71
85
 
72
- - `web_status` show configured provider status without secrets.
73
- - `/web-status` — command version of the status check.
86
+ Extracts readable content from a URL. Auto-selects backend: static (JSDOM) dynamic (Firecrawl) full (Crawl4AI), with extraction diagnostics showing fallback attempts.
74
87
 
75
- ## Library structure
88
+ ```
89
+ web_extract url="https://docs.ansible.com/..."
90
+ web_extract url="https://riven.tv/" mode=static
91
+ web_extract url="https://example.com" mode=dynamic prompt="Extract pricing plans"
92
+ ```
93
+
94
+ Parameters:
95
+
96
+ | Parameter | Type | Default | Description |
97
+ |---|---|---|---|
98
+ | `url` | string | — | URL to extract |
99
+ | `mode` | string | `auto` | `auto`, `static`, `dynamic`, or `full` |
100
+ | `prompt` | string | — | Prompt for JSON extraction (dynamic mode) |
101
+ | `schema` | any | — | JSON schema for structured extraction (dynamic mode) |
102
+ | `content_chars` | number | 20000 | Max content chars |
103
+ | `wait_for` | number | — | Milliseconds to wait for Firecrawl dynamic rendering. Crawl4AI `/md` full mode may ignore this. |
104
+ | `mobile` | boolean | false | Emulate mobile viewport (dynamic mode) |
105
+
106
+ **Mode behavior:**
107
+
108
+ | Mode | Backend | Best for | API key needed |
109
+ |---|---|---|---|
110
+ | `static` | JSDOM+Readability | Simple static pages, blog posts, docs | No |
111
+ | `dynamic` | Firecrawl Scrape | JS-rendered pages, dynamic content | Maybe |
112
+ | `full` | Crawl4AI | JS-heavy SPA, complex rendering | Maybe |
113
+ | `auto` (default) | static → dynamic → full | Unknown page type | Maybe |
114
+
115
+ In `auto` mode, fallbacks are noted in the output (e.g., `[Extraction fell back to Firecrawl Scrape (dynamic mode)]`). If `static` extraction fails, the tool gracefully escalates to heavier backends.
116
+
117
+ > ⚠️ **Note on Firecrawl Scrape**: Fails on bot-protected sites (Ansible docs, many CDN-backed doc sites). Falls back to `full` mode (Crawl4AI) in `auto` mode.
118
+
119
+ ### `web_map` — Site URL discovery
120
+
121
+ Discovers URLs from a site using Firecrawl Map. Best on base domains; may return fewer results on sub-paths.
122
+
123
+ ```
124
+ web_map url="https://riven.tv"
125
+ web_map url="https://docs.example.com" sitemap=only
126
+ ```
127
+
128
+ Parameters: `url`, `limit` (default 100), `include_subdomains`, `search`, `sitemap`, `use_index`, `ignore_cache`.
129
+
130
+ ### `web_crawl` — Site crawl
131
+
132
+ Crawls pages from a site. Two modes:
133
+
134
+ - **`light`** (default): Firecrawl Crawl — conservative, docs-focused, single URL.
135
+ - **`full`**: Crawl4AI Crawl — headless browser, rendered data, media, links, up to 100 URLs.
76
136
 
77
- The extension is split into `lib/` modules:
137
+ ```
138
+ web_crawl url="https://docs.example.com" limit=10 # Firecrawl light mode
139
+ web_crawl urls=["https://a.com","https://b.com"] mode=full # Crawl4AI full mode
140
+ web_crawl url="https://example.com" mode=light poll=true # Poll for completion
141
+ ```
142
+
143
+ ### `web_screenshot` — Page screenshot
144
+
145
+ Captures a full-page PNG screenshot using Crawl4AI. Returns base64-encoded PNG.
146
+
147
+ ```
148
+ web_screenshot url="https://example.com"
149
+ web_screenshot url="https://example.com" wait_for=5 wait_for_images=true
150
+ ```
151
+
152
+ ### `web_pdf` — Page PDF
153
+
154
+ Generates a PDF document using Crawl4AI. Returns base64-encoded PDF.
155
+
156
+ ```
157
+ web_pdf url="https://example.com/article"
158
+ ```
159
+
160
+ ### `web_status` — Provider status
161
+
162
+ Shows all provider configuration status and Crawl4AI server health.
163
+
164
+ ```
165
+ web_status
166
+ ```
167
+
168
+ Typical output:
169
+
170
+ ```json
171
+ {
172
+ "brave": { "apiKeyFound": true, "apiKeySource": "process.env" },
173
+ "searxng": { "baseUrl": "http://172.30.55.22:8888", ... },
174
+ "firecrawl": { "baseUrl": "http://172.30.55.22:3002/v2", ... },
175
+ "crawl4ai": {
176
+ "baseUrl": "http://172.30.55.22:11235",
177
+ ...
178
+ "health": { "status": "healthy", "version": "0.5.0", ... }
179
+ }
180
+ }
181
+ ```
182
+
183
+ ## Library structure
78
184
 
79
185
  | Module | Contents |
80
186
  |--------|----------|
81
187
  | `lib/config.ts` | Environment loading, config helpers for all providers |
82
- | `lib/format.ts` | Text sanitization, truncation, search/scrape result formatting |
188
+ | `lib/format.ts` | Text sanitization, truncation, crawl/scrape result formatting |
83
189
  | `lib/content.ts` | Readable content extraction (JSDOM + Readability + Turndown) |
84
190
  | `lib/retry.ts` | Retry with exponential backoff for transient HTTP failures |
85
- | `lib/brave.ts` | Brave Search API fetch client |
86
- | `lib/searxng.ts` | SearXNG metasearch fetch client |
87
- | `lib/firecrawl.ts` | Firecrawl API fetch client with v2→v1 fallback |
88
-
89
- ## Retry behavior
90
-
91
- All HTTP-backed tools (`brave_search`, `searxng_search`, `firecrawl_*`) use a `withRetry` wrapper with exponential backoff (up to 2 retries, ~1s initial delay). Non-transient errors (auth, validation, not found) are never retried.
92
-
93
- ## Migration from 0.1.x
94
-
95
- - `brave_content` has been renamed to `web_content`. Update any agent instructions or skills that reference `brave_content` to use `web_content` instead. The tool API and behavior are unchanged.
191
+ | `lib/brave.ts` | Brave Search API fetch client (internal) |
192
+ | `lib/searxng.ts` | SearXNG metasearch fetch client (internal) |
193
+ | `lib/firecrawl.ts` | Firecrawl API fetch client with v2→v1 fallback (internal) |
194
+ | `lib/crawl4ai.ts` | Crawl4AI Docker API fetch client (internal) |
195
+ | `lib/search.ts` | Unified search orchestrator — probes backends, fallback chain |
196
+ | `lib/extract.ts` | Unified extraction orchestrator — mode-based backend selection |
197
+
198
+ ## Migration from 0.3.x
199
+
200
+ v0.4 replaces the 14 individual backend-specific tools with 7 unified tools:
201
+
202
+ | v0.3 tool | v0.4 replacement |
203
+ |---|---|
204
+ | `brave_search` | `web_search` with `backend: "brave"` |
205
+ | `searxng_search` | `web_search` with `backend: "searxng"` |
206
+ | `firecrawl_search` | `web_search` with `backend: "firecrawl"` |
207
+ | `web_content` | `web_extract` with `mode: "static"` |
208
+ | `firecrawl_scrape` | `web_extract` with `mode: "dynamic"` |
209
+ | `crawl4ai_scrape` | `web_extract` with `mode: "full"` |
210
+ | `firecrawl_map` | `web_map` (same behavior) |
211
+ | `firecrawl_crawl` | `web_crawl` with `mode: "light"` |
212
+ | `crawl4ai_crawl` | `web_crawl` with `mode: "full"` |
213
+ | `crawl4ai_stream` | (removed — use `web_crawl` with `mode: "full"`) |
214
+ | `crawl4ai_screenshot` | `web_screenshot` (same behavior) |
215
+ | `crawl4ai_pdf` | `web_pdf` (same behavior) |
216
+ | `crawl4ai_status` | Merged into `web_status` |
217
+ | `web_status` | `web_status` (enhanced with Crawl4AI health) |
218
+
219
+ All v0.3 tool names were removed in v0.4. Update any agent instructions or skills that reference the old names.
96
220
 
97
221
  ## Development
98
222
 
@@ -103,15 +227,3 @@ npm test
103
227
  # Run only unit tests
104
228
  npm run test:unit
105
229
  ```
106
-
107
- ## Practical Guidance
108
-
109
- - Use `searxng_search` first for general web search, docs lookup, current facts, and source discovery; it is fast, self-hosted, and avoids hosted API costs/rate limits.
110
- - Use `brave_search` as a fast hosted fallback when SearXNG results are weak/unavailable, or when an independent search index is useful. Use `include_content` sparingly.
111
- - Use `web_content` for fast known-URL article/docs extraction when simple readable markdown is enough.
112
- - Use `firecrawl_search` when SearXNG/Brave are unavailable, when Firecrawl search is preferred, or when search results should include scraped markdown.
113
- - Use `firecrawl_scrape` for known URLs when extraction quality matters, pages are dynamic, links are needed, or structured JSON extraction is requested.
114
- - Use `firecrawl_map` before crawling to discover candidate URLs and keep crawls targeted.
115
- - Use `firecrawl_crawl` only when multiple pages are required; keep limits conservative and use include/exclude paths.
116
- - When answering from web content, cite source URLs from result links or metadata.
117
- - Use `web_status` when provider configuration is uncertain or a web tool fails due to credentials/config.