pi-web-toolkit 0.2.0 → 0.2.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
@@ -18,6 +18,28 @@ Web research toolkit for [pi](https://pi.dev) agents. Search via SearXNG, fetch
18
18
  | **`web_batch_fetch`** | [scrapling](https://github.com/D4Vinci/Scrapling) | Fetch 2–15 pages in parallel for research synthesis | 3 concurrent (max 5) |
19
19
  | **`web_browse`** | [agent-browser](https://github.com/vercel-labs/agent-browser) | Interact with a page (click, scroll, fill) then extract content | 25 actions |
20
20
 
21
+ ## Tools Preview
22
+
23
+ A quick look at how pi renders toolkit calls while an agent searches, fetches, batches, and browses the web.
24
+
25
+ <table>
26
+ <tr>
27
+ <td width="50%"><strong>Multi-tool research flow</strong><br><img src="docs/assets/screenshots/tools-workflow-preview.png" alt="pi-web-toolkit multi-tool research preview"></td>
28
+ <td width="50%"><strong><code>web_search</code> expanded results</strong><br><img src="docs/assets/screenshots/web-search-results-expanded.png" alt="web_search expanded results"></td>
29
+ </tr>
30
+ <tr>
31
+ <td width="50%"><strong><code>web_batch_fetch</code> progress</strong><br><img src="docs/assets/screenshots/web-batch-fetch-progress.png" alt="web_batch_fetch progress"></td>
32
+ <td width="50%"><strong><code>web_batch_fetch</code> results</strong><br><img src="docs/assets/screenshots/web-batch-fetch-results.png" alt="web_batch_fetch results"></td>
33
+ </tr>
34
+ <tr>
35
+ <td width="50%"><strong><code>web_fetch</code> result preview</strong><br><img src="docs/assets/screenshots/web-fetch-summary.png" alt="web_fetch result preview"></td>
36
+ <td width="50%"><strong><code>web_browse</code> headless browser flow</strong><br><img src="docs/assets/screenshots/web-browse-headless.png" alt="web_browse headless browser flow"></td>
37
+ </tr>
38
+ <tr>
39
+ <td colspan="2"><strong>End-to-end research summary</strong><br><img src="docs/assets/screenshots/web-research-workflow.png" alt="end-to-end web research workflow"></td>
40
+ </tr>
41
+ </table>
42
+
21
43
  ## Quick Start
22
44
 
23
45
  ### 1. Install external dependencies
@@ -78,12 +100,19 @@ pi-web-toolkit/
78
100
  ├── extensions/
79
101
  │ ├── index.ts # Unified entry point — registers all 4 tools
80
102
  │ ├── utils/
103
+ │ │ ├── cli-runner.ts # Unified CLI process spawning with timeout/AbortSignal
104
+ │ │ ├── content-preview.ts # Intelligent content extraction from scraped pages
105
+ │ │ ├── output-sink.ts # Truncation + temp-file fallback
106
+ │ │ ├── render-helpers.ts # URL abbreviations, text normalization, error formatting for TUI
81
107
  │ │ ├── scrapling.ts # Reusable scrapling CLI wrapper (shared by fetch + batch)
108
+ │ │ ├── tool-factory.ts # Common tool registration patterns
82
109
  │ │ └── agent-browser.ts # agent-browser CLI wrapper (shared by web_browse)
83
110
  │ ├── web_search.ts # SearXNG search tool
84
111
  │ ├── web_fetch.ts # Single-page scrapling fetcher
85
112
  │ ├── web_batch_fetch.ts # Parallel scrapling fetcher
86
113
  │ └── web_browse.ts # Interactive browser automation (agent-browser)
114
+ ├── test/
115
+ │ └── content-preview/ # Automated test suite with fixtures & snapshots
87
116
  ├── docs/
88
117
  │ ├── tools.md # Full parameter specs
89
118
  │ └── guide.md # Decision tree & tool comparison
@@ -95,7 +124,7 @@ pi-web-toolkit/
95
124
 
96
125
  **Design principles:**
97
126
  - **Unified registration** — `index.ts` is the single source of truth for what pi loads.
98
- - **Shared utilities** — `utils/scrapling.ts` and `utils/agent-browser.ts` encapsulate the CLI wrappers and fallback logic; tool files import only from `utils/`, never from each other.
127
+ - **Shared utilities** — `utils/` modules encapsulate CLI spawning, content extraction, output truncation, TUI formatting, and common registration patterns; tool files import only from `utils/`, never from each other.
99
128
  - **Per-tool isolation** — each tool owns its own schema, execute logic, and TUI renderer; no cross-imports except via `utils/`.
100
129
  - **Runtime config** — environment variables are read at execute time, not build time.
101
130
 
@@ -112,7 +141,10 @@ pi-web-toolkit/
112
141
  pi install ./
113
142
 
114
143
  # Type-check (no build step; pi loads TypeScript directly)
115
- npx tsc --noEmit
144
+ npm run typecheck
145
+
146
+ # Run tests
147
+ npm run test
116
148
 
117
149
  # Verify external CLI dependencies
118
150
  scrapling --help
@@ -25,6 +25,48 @@ export interface AgentBrowserBatchItem {
25
25
  error?: string | null;
26
26
  }
27
27
 
28
+ function isRecord(value: unknown): value is Record<string, unknown> {
29
+ return typeof value === "object" && value !== null && !Array.isArray(value);
30
+ }
31
+
32
+ function isBatchItem(value: unknown): value is AgentBrowserBatchItem {
33
+ return isRecord(value)
34
+ && typeof value.success === "boolean"
35
+ && Array.isArray(value.command)
36
+ && value.command.every((part) => typeof part === "string");
37
+ }
38
+
39
+ function describeBatchOutput(value: unknown): string {
40
+ if (Array.isArray(value)) return `array with ${value.length} item(s)`;
41
+ if (isRecord(value)) return `object with keys: ${Object.keys(value).join(", ") || "(none)"}`;
42
+ return typeof value;
43
+ }
44
+
45
+ export function parseAgentBrowserBatchOutput(stdout: string): AgentBrowserBatchItem[] {
46
+ const parsed = JSON.parse(stdout) as unknown;
47
+
48
+ if (Array.isArray(parsed)) {
49
+ if (parsed.every(isBatchItem)) return parsed;
50
+ throw new Error(`Expected every batch result item to contain { success, command }; got ${describeBatchOutput(parsed)}`);
51
+ }
52
+
53
+ if (isBatchItem(parsed)) {
54
+ return [parsed];
55
+ }
56
+
57
+ if (isRecord(parsed)) {
58
+ for (const key of ["results", "items", "data", "commands"]) {
59
+ const candidate = parsed[key];
60
+ if (Array.isArray(candidate)) {
61
+ if (candidate.every(isBatchItem)) return candidate;
62
+ throw new Error(`Expected ${key} to contain batch result items; got ${describeBatchOutput(candidate)}`);
63
+ }
64
+ }
65
+ }
66
+
67
+ throw new Error(`Expected JSON array of batch results; got ${describeBatchOutput(parsed)}`);
68
+ }
69
+
28
70
  function requireString(action: BrowseAction, field: "selector" | "value" | "key"): string {
29
71
  const value = action[field] as string | undefined;
30
72
  if (typeof value !== "string" || value.length === 0) {
@@ -150,7 +192,7 @@ export async function runAgentBrowserBatch(
150
192
  }
151
193
 
152
194
  try {
153
- return JSON.parse(result.stdout) as AgentBrowserBatchItem[];
195
+ return parseAgentBrowserBatchOutput(result.stdout);
154
196
  } catch (err: any) {
155
197
  throw new Error(
156
198
  `Failed to parse agent-browser output: ${err.message}\nstdout: ${result.stdout}\nstderr: ${result.stderr}`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-web-toolkit",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
4
4
  "description": "Web research toolkit for the pi coding agent. Search via SearXNG, fetch static pages with scrapling, browse interactively via agent-browser, and batch-read sources in parallel.",
5
5
  "author": "Wade Huang <fastwade11@gmail.com>",
6
6
  "license": "MIT",
@@ -19,7 +19,8 @@
19
19
  },
20
20
  "scripts": {
21
21
  "typecheck": "tsc --noEmit",
22
- "test": "npx tsx test/content-preview/test.ts",
22
+ "test": "npx tsx test/content-preview/test.ts && npx tsx test/agent-browser/test.ts",
23
+ "test:agent-browser": "npx tsx test/agent-browser/test.ts",
23
24
  "test:approve": "npx tsx test/content-preview/test.ts --approve"
24
25
  },
25
26
  "devDependencies": {