@bacnh85/pi-web 0.6.0 → 0.6.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/CHANGELOG.md +19 -0
- package/extensions/index.ts +22 -66
- package/extensions/lib/agy.ts +1 -1
- package/package.json +8 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,24 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.6.2 (2026-08-30)
|
|
4
|
+
|
|
5
|
+
### Changed
|
|
6
|
+
|
|
7
|
+
- Trimmed static prompt overhead ~385 tokens/turn: compressed the injected
|
|
8
|
+
`Web Tool Routing` guidance block (1,247 -> 281 chars, same routing table
|
|
9
|
+
+ backend rules), cut all 7 tools' promptGuidelines to <=2 unique lines,
|
|
10
|
+
and shortened web_crawl/web_screenshot schema descriptions. One
|
|
11
|
+
hook.test.ts assertion updated to the compressed phrasing. No tool,
|
|
12
|
+
parameter, or default changed.
|
|
13
|
+
|
|
14
|
+
## 0.6.1 (2026-08-19)
|
|
15
|
+
|
|
16
|
+
### Changed
|
|
17
|
+
|
|
18
|
+
- `web_extract` agy backend default model updated to `gemini-3.7-flash-medium`
|
|
19
|
+
— the current Flash generation in agy 1.1.x (3.6 is still served, this just
|
|
20
|
+
follows the latest).
|
|
21
|
+
|
|
3
22
|
## 0.6.0 (2026-08-07)
|
|
4
23
|
|
|
5
24
|
### Features
|
package/extensions/index.ts
CHANGED
|
@@ -57,27 +57,14 @@ const crawl4aiControlSchema = {
|
|
|
57
57
|
// the guidance travels with the package and disappears when pi-web is absent.
|
|
58
58
|
const WEB_ROUTING_GUIDANCE = `## Web Tool Routing (pi-web)
|
|
59
59
|
|
|
60
|
-
|
|
60
|
+
- **web_search** — web search (auto: SearXNG → Brave → Firecrawl; force via \`backend\`, tune via \`engines\`).
|
|
61
|
+
- **web_extract** — URL → markdown (auto: static JSDOM → dynamic Firecrawl → full Crawl4AI → agy; force via \`mode\`; prompt+schema for JSON extraction).
|
|
62
|
+
- **web_map** — discover site URLs (Firecrawl Map).
|
|
63
|
+
- **web_crawl** — multi-page crawl: \`mode: "light"\` (Firecrawl, url) or \`mode: "full"\` (Crawl4AI, urls[]).
|
|
64
|
+
- **web_screenshot** / **web_pdf** — page capture (Crawl4AI).
|
|
65
|
+
- **web_status** — provider config + health.
|
|
61
66
|
|
|
62
|
-
-
|
|
63
|
-
\`backend\` for explicit control, \`engines\` for SearXNG tuning.
|
|
64
|
-
- **\`web_extract\`** — Extract readable content from a URL (auto: static JSDOM
|
|
65
|
-
→ dynamic Firecrawl → full Crawl4AI → agy model-backed). Use \`mode\` for
|
|
66
|
-
explicit control.
|
|
67
|
-
- **\`web_map\`** — Discover URLs from a site (Firecrawl Map).
|
|
68
|
-
- **\`web_crawl\`** — Crawl multiple pages. \`mode: "light"\` (Firecrawl) or
|
|
69
|
-
\`mode: "full"\` (Crawl4AI).
|
|
70
|
-
- **\`web_screenshot\`** / **\`web_pdf\`** — Visual/page capture (Crawl4AI).
|
|
71
|
-
- **\`web_status\`** — Check provider configuration and server health.
|
|
72
|
-
|
|
73
|
-
Backend selection rules:
|
|
74
|
-
|
|
75
|
-
- Firecrawl Search has poor semantic accuracy on domain-specific queries; prefer
|
|
76
|
-
SearXNG or Brave for precision (force via \`backend\`).
|
|
77
|
-
- Firecrawl Scrape fails on bot-protected sites (e.g. Ansible docs); Crawl4AI
|
|
78
|
-
handles those (force via \`mode: "full"\`), and agy (Gemini/Claude read_url)
|
|
79
|
-
handles the rest as a last-resort fallback (force via \`mode: "agy"\`).
|
|
80
|
-
- Always cite source URLs when web results materially support an answer.`;
|
|
67
|
+
Rules: Firecrawl Search is weak on domain-specific queries — prefer SearXNG/Brave; Firecrawl Scrape fails on bot-protected sites — use Crawl4AI (\`mode: "full"\`) then agy (\`mode: "agy"\`); cite source URLs.`;
|
|
81
68
|
|
|
82
69
|
|
|
83
70
|
// ---------------------------------------------------------------------------
|
|
@@ -92,13 +79,7 @@ export default function piWebExtension(pi: ExtensionAPI) {
|
|
|
92
79
|
description:
|
|
93
80
|
"Search the web. Auto-selects backends: SearXNG, Brave, Firecrawl.",
|
|
94
81
|
promptSnippet: "Search current web results",
|
|
95
|
-
promptGuidelines: [
|
|
96
|
-
"Source discovery, docs, facts, and general search.",
|
|
97
|
-
"Broad discovery uses SearXNG; precision/site/docs use Brave; Firecrawl is fallback.",
|
|
98
|
-
"Force backend via backend:'brave'|'searxng' for poor auto results.",
|
|
99
|
-
"Use engines='google,github' for SearXNG tuning.",
|
|
100
|
-
"Cite source URLs.",
|
|
101
|
-
],
|
|
82
|
+
promptGuidelines: ["Source discovery, docs, facts. Precision/site/docs → Brave via backend:'brave'; tune SearXNG via engines.", "Cite source URLs."],
|
|
102
83
|
parameters: Type.Object({
|
|
103
84
|
query: Type.String(),
|
|
104
85
|
count: Type.Optional(Type.Number({ default: 5 })),
|
|
@@ -140,14 +121,7 @@ export default function piWebExtension(pi: ExtensionAPI) {
|
|
|
140
121
|
description:
|
|
141
122
|
"Extract readable content from a URL. Auto mode: static\u2192dynamic\u2192full\u2192agy.",
|
|
142
123
|
promptSnippet: "Extract readable webpage content as markdown",
|
|
143
|
-
promptGuidelines: [
|
|
144
|
-
"Clean markdown from a known URL.",
|
|
145
|
-
"mode: 'static' (no API key, JSDOM), 'dynamic' (Firecrawl JS), 'full' (Crawl4AI), 'agy' (Gemini/Claude via agy).",
|
|
146
|
-
"'auto' tries static\u2192dynamic\u2192full\u2192agy; see diagnostics for fallback chain.",
|
|
147
|
-
"mode: 'agy' uses agy's native read_url for bot-protected/JS-heavy pages \u2014 last-resort fallback in auto.",
|
|
148
|
-
"Use prompt+schema for structured JSON extraction (dynamic/agy modes).",
|
|
149
|
-
"Cite the source URL.",
|
|
150
|
-
],
|
|
124
|
+
promptGuidelines: ["Markdown from a known URL; prompt+schema for structured JSON extraction.", "Cite the source URL."],
|
|
151
125
|
parameters: Type.Object({
|
|
152
126
|
url: Type.String(),
|
|
153
127
|
mode: Type.Optional(Type.Union(
|
|
@@ -191,11 +165,7 @@ export default function piWebExtension(pi: ExtensionAPI) {
|
|
|
191
165
|
description:
|
|
192
166
|
"Discover site URLs via Firecrawl Map.",
|
|
193
167
|
promptSnippet: "Map site URLs",
|
|
194
|
-
promptGuidelines: [
|
|
195
|
-
"Discover site URLs before crawling. Prefer web_extract for small jobs.",
|
|
196
|
-
"Best on base domains. sitemap:'only' for sub-path discovery.",
|
|
197
|
-
"Keep limits small unless broad discovery is requested.",
|
|
198
|
-
],
|
|
168
|
+
promptGuidelines: ["URL discovery before crawling; prefer web_extract for small jobs."],
|
|
199
169
|
parameters: Type.Object({
|
|
200
170
|
url: Type.String(),
|
|
201
171
|
limit: Type.Optional(Type.Number({ default: 100 })),
|
|
@@ -234,21 +204,17 @@ export default function piWebExtension(pi: ExtensionAPI) {
|
|
|
234
204
|
description:
|
|
235
205
|
"Crawl pages. Firecrawl 'light' or Crawl4AI 'full' headless mode.",
|
|
236
206
|
promptSnippet: "Crawl a small site section",
|
|
237
|
-
promptGuidelines: [
|
|
238
|
-
"Prefer web_map + web_extract over crawl for small jobs.",
|
|
239
|
-
"'light'=Firecrawl (url param), 'full'=Crawl4AI (urls[] param).",
|
|
240
|
-
"Keep limit low (default 10).",
|
|
241
|
-
],
|
|
207
|
+
promptGuidelines: ["'light'=Firecrawl (url), 'full'=Crawl4AI (urls[]). Prefer web_map + web_extract for small jobs."],
|
|
242
208
|
parameters: Type.Object({
|
|
243
|
-
url: Type.Optional(Type.String({ description: "URL for
|
|
244
|
-
urls: Type.Optional(Type.Array(Type.String(), { description: "URLs for
|
|
209
|
+
url: Type.Optional(Type.String({ description: "URL for mode:'light' (Firecrawl)." })),
|
|
210
|
+
urls: Type.Optional(Type.Array(Type.String(), { description: "URLs for mode:'full' (Crawl4AI), up to 100." })),
|
|
245
211
|
mode: Type.Optional(Type.Union([Type.Literal("light"), Type.Literal("full")], { default: "light", description: "'light'(Firecrawl) or 'full'(Crawl4AI)." })),
|
|
246
212
|
limit: Type.Optional(Type.Number({ default: 10 })),
|
|
247
|
-
include_paths: Type.Optional(Type.String({ description: "Comma-separated paths
|
|
248
|
-
exclude_paths: Type.Optional(Type.String({ description: "Comma-separated paths
|
|
249
|
-
poll: Type.Optional(Type.Boolean({ default: false, description: "Poll
|
|
250
|
-
browser_config: Type.Optional(Type.Any({ description: "BrowserConfig JSON (full mode
|
|
251
|
-
crawler_config: Type.Optional(Type.Any({ description: "CrawlerRunConfig JSON (full mode
|
|
213
|
+
include_paths: Type.Optional(Type.String({ description: "Comma-separated include paths (light mode)." })),
|
|
214
|
+
exclude_paths: Type.Optional(Type.String({ description: "Comma-separated exclude paths (light mode)." })),
|
|
215
|
+
poll: Type.Optional(Type.Boolean({ default: false, description: "Poll until completion (light mode)." })),
|
|
216
|
+
browser_config: Type.Optional(Type.Any({ description: "BrowserConfig JSON (full mode)." })),
|
|
217
|
+
crawler_config: Type.Optional(Type.Any({ description: "CrawlerRunConfig JSON (full mode)." })),
|
|
252
218
|
content_chars: Type.Optional(Type.Number({ default: 20000 })),
|
|
253
219
|
...firecrawlControlSchema,
|
|
254
220
|
...crawl4aiControlSchema,
|
|
@@ -322,14 +288,11 @@ export default function piWebExtension(pi: ExtensionAPI) {
|
|
|
322
288
|
description:
|
|
323
289
|
"Full-page PNG screenshot via Crawl4AI.",
|
|
324
290
|
promptSnippet: "Screenshot a webpage",
|
|
325
|
-
promptGuidelines: [
|
|
326
|
-
"Use when web_extract fails on JS-heavy or bot-protected pages.",
|
|
327
|
-
"wait_for (default 2s) delays capture for dynamic content.",
|
|
328
|
-
],
|
|
291
|
+
promptGuidelines: ["Full-page PNG; use when web_extract fails on JS-heavy pages."],
|
|
329
292
|
parameters: Type.Object({
|
|
330
293
|
url: Type.String(),
|
|
331
294
|
wait_for: Type.Optional(Type.Number({ default: 2, description: "Seconds to wait before capture." })),
|
|
332
|
-
wait_for_images: Type.Optional(Type.Boolean({ default: false
|
|
295
|
+
wait_for_images: Type.Optional(Type.Boolean({ default: false })),
|
|
333
296
|
...crawl4aiControlSchema,
|
|
334
297
|
...sharedControlSchema,
|
|
335
298
|
}),
|
|
@@ -362,10 +325,7 @@ export default function piWebExtension(pi: ExtensionAPI) {
|
|
|
362
325
|
description:
|
|
363
326
|
"PDF document via Crawl4AI.",
|
|
364
327
|
promptSnippet: "PDF a webpage",
|
|
365
|
-
promptGuidelines: [
|
|
366
|
-
"Printable or archivable page snapshot.",
|
|
367
|
-
"Returns base64 PDF string.",
|
|
368
|
-
],
|
|
328
|
+
promptGuidelines: ["Printable/archivable page snapshot; returns base64 PDF."],
|
|
369
329
|
parameters: Type.Object({
|
|
370
330
|
url: Type.String(),
|
|
371
331
|
...crawl4aiControlSchema,
|
|
@@ -392,11 +352,7 @@ export default function piWebExtension(pi: ExtensionAPI) {
|
|
|
392
352
|
description:
|
|
393
353
|
"Show web provider config status without printing secrets.",
|
|
394
354
|
promptSnippet: "Check web provider config and server status",
|
|
395
|
-
promptGuidelines: [
|
|
396
|
-
"Check which backends are configured and their server status.",
|
|
397
|
-
"Never prints secrets — reports only presence and source.",
|
|
398
|
-
"apiKeyFound:false is normal for self-hosted Firecrawl; check ready field.",
|
|
399
|
-
],
|
|
355
|
+
promptGuidelines: ["Reports backend presence/health; never prints secrets."],
|
|
400
356
|
parameters: Type.Object({}),
|
|
401
357
|
async execute(_id: string, _params: Record<string, unknown>, signal: AbortSignal, _onUpdate: unknown, ctx: any) {
|
|
402
358
|
const cwd = cwdFromContext(ctx);
|
package/extensions/lib/agy.ts
CHANGED
|
@@ -17,7 +17,7 @@ const cp = _require("node:child_process") as typeof import("node:child_process")
|
|
|
17
17
|
const AGY_FETCH_TIMEOUT_MS = 90_000; // agy needs time for model call + web fetch
|
|
18
18
|
const AGY_PROBE_TIMEOUT_MS = 5_000;
|
|
19
19
|
const AGY_MAX_OUTPUT_BYTES = 200_000; // bound output to protect Pi context
|
|
20
|
-
export const AGY_MODEL = "gemini-3.
|
|
20
|
+
export const AGY_MODEL = "gemini-3.7-flash-medium"; // ponytail: fixed default; users needing model control use agy_execute
|
|
21
21
|
|
|
22
22
|
// Cache install status with a TTL — spawnSync blocks the event loop up to
|
|
23
23
|
// AGY_PROBE_TIMEOUT_MS, and web_status/extract can call this repeatedly.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bacnh85/pi-web",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.1",
|
|
4
4
|
"description": "Pi extension for web search, page extraction, Firecrawl scraping/crawling, and Crawl4AI headless browser crawling.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -59,7 +59,13 @@
|
|
|
59
59
|
"@types/node": "^26.0.1",
|
|
60
60
|
"@types/turndown": "^5.0.6",
|
|
61
61
|
"chai": "^6.2.2",
|
|
62
|
-
"mocha": "^11.
|
|
62
|
+
"mocha": "^11.8.0",
|
|
63
63
|
"tsx": "^4.22.4"
|
|
64
|
+
},
|
|
65
|
+
"overrides": {
|
|
66
|
+
"serialize-javascript@>=5.0.0 <7.0.5": "^7.0.5",
|
|
67
|
+
"js-yaml@>=4.0.0 <4.3.1": "^4.3.1",
|
|
68
|
+
"brace-expansion@>=2.0.0 <2.1.4": "^2.1.4",
|
|
69
|
+
"diff": "^8.0.3"
|
|
64
70
|
}
|
|
65
71
|
}
|