pi web-search #
A pi extension that supplies two live-web tools backed by SearXNG:
search— run a SearXNG query; returns result titles, URLs, and snippets.fetch— download a page and read it as plain text (HTML is converted; long pages are chunked via anoffsetparameter).
The tools are deliberately thin. Orchestration — running searches from multiple
angles, fetching primary sources, cross-checking claims, and keeping the noisy
search/page dumps out of your main context — lives in a subagent preset
(web-search.md) rather than inside the extension. Delegating research to that
preset keeps the raw results in a throwaway context and returns only a concise,
cited answer to the main conversation.
How it works #
searchandfetchare ordinary tools registered on the session. Any agent (main or sub) with them in its tool set can call them.- The bundled
web-searchpreset is a pi-subagent definition withtools: search, fetchand a research-method system prompt: search broadly, fetch primary sources, quote verbatim excerpts, cite every claim, never cite an unfetched page. Launching thesubagenttool with{ "preset": "web-search", "task": "..." }runs the research in an isolated context and returns only the cited answer. - Because a subagent inherits your installed extensions and its
--toolsallowlist activates the matching registered tools, the preset getssearchandfetcheven if they're hidden in your interactive session (see Configuration).
Requirements #
-
A SearXNG instance with the JSON output format enabled — in the instance's
settings.yml:search: formats: - html - json -
For the research preset: the
subagenttool installed. Thesearch/fetchtools work on their own without it.
Installation #
Install as a pi package directly from the repository:
pi install https://tangled.org/did:plc:a2gmxtenwth7e4ghm6ajpchj/
The trailing slash is required. Append @<tag-or-commit> to pin a ref.
Manage it afterwards with pi list, pi update, and pi remove (same
source string).
From a local clone #
Symlink (or copy) the web-search/ directory into pi's extension directory:
ln -s "$(pwd)/web-search" ~/.pi/agent/extensions/web-search
or reference it from ~/.pi/agent/settings.json:
{
"extensions": ["/path/to/pi-web-search/web-search"]
}
The research preset #
search/fetch are usable as soon as the extension is installed. To get the
web-search research subagent, install the bundled preset with the command:
/websearch-install-preset # into ~/.pi/agent/subagents (user, all projects)
/websearch-install-preset project # into <project>/.pi/subagents (this project only)
It copies web-search/web-search.md into the subagents directory, confirms
before overwriting a differing copy, and warns if the subagent tool isn't
installed (the preset needs it to run). Or do it by hand:
ln -s "$(pwd)/web-search/web-search.md" ~/.pi/agent/subagents/web-search.md
Edit the installed copy to pin a model or change the thinking level. By
default the preset inherits the caller's model.
Configuration #
Sources, later overrides earlier:
- Built-in defaults
~/.pi/agent/web-search.json(global)<project>/.pi/web-search.json(only when the project is trusted)SEARXNG_BASE_URLenvironment variable (base URL only)
The easiest path is the /websearch command inside pi: it prompts for the
base URL, tests the connection, and saves the global config file.
All options:
{
"baseUrl": "http://localhost:8888",
"maxResults": 8,
"requestTimeoutMs": 30000,
"blockPrivateAddresses": false,
"hideFromMainSession": false
}
| Key | Default | Description |
|---|---|---|
baseUrl |
— (required) | SearXNG base URL (http:// is assumed when no scheme is given) |
maxResults |
8 |
Search results returned per query |
requestTimeoutMs |
30000 |
Timeout for search and page-fetch requests |
blockPrivateAddresses |
false |
Refuse fetch requests to hosts that resolve to private, loopback, link-local, or CGNAT addresses (re-checked on every redirect hop). Off by default so local and tailnet pages stay reachable; turn it on if you don't want pages from the open web to be able to steer a fetch at your LAN or cloud metadata endpoints |
hideFromMainSession |
false |
Deactivate search/fetch in interactive (TUI) sessions so the main agent doesn't call them directly. They stay registered (so the web-search subagent preset still gets them) but are hidden from the interactive tool list; re-enable with /tools. Subagents are unaffected |
Model and thinking level for research now live in the preset's frontmatter
(web-search.md) and in pi-subagent's ~/.pi/agent/subagent.json, not here.
Usage #
Anything that makes you want facts from the live web, delegated to the preset:
What's new in the latest SQLite release? Use the web-search subagent.
The main agent launches subagent with { "preset": "web-search", "task": ... };
the preset cannot see the conversation, so the task must be self-contained.
You can also call search/fetch directly when you want raw results in the
current context — though their descriptions nudge toward the preset, since the
raw output is large and noisy.
Files #
| File | Purpose |
|---|---|
web-search/index.ts |
Extension entry: search and fetch tools, TUI rendering, /websearch and /websearch-install-preset commands, optional hide-in-TUI behavior |
web-search/web-search.md |
The research subagent preset (system prompt + tools: search, fetch) |
web-search/searxng.ts |
SearXNG JSON API client + result formatting |
web-search/page.ts |
Page fetching and dependency-free HTML → text extraction |
web-search/config.ts |
Layered config loading/saving |
web-search/http.ts |
fetch with timeout + abort propagation |
Development #
Typechecking resolves pi's packages from the installed CLI; symlink them into
node_modules (adjust the path to your install):
PI_PKG=$(dirname "$(readlink -f "$(which pi)")")/../lib/node_modules/@earendil-works/pi-coding-agent
mkdir -p node_modules/@earendil-works
ln -sfn "$PI_PKG" node_modules/@earendil-works/pi-coding-agent
ln -sfn "$PI_PKG/node_modules/@earendil-works/pi-tui" node_modules/@earendil-works/pi-tui
ln -sfn "$PI_PKG/node_modules/@earendil-works/pi-ai" node_modules/@earendil-works/pi-ai
ln -sfn "$PI_PKG/node_modules/@earendil-works/pi-agent-core" node_modules/@earendil-works/pi-agent-core
ln -sfn "$PI_PKG/node_modules/typebox" node_modules/typebox
npx -y -p typescript tsc -p tsconfig.json
Quick live test without installing:
SEARXNG_BASE_URL=http://localhost:8888 \
pi -e ./web-search/index.ts -p --no-session \
"Use the search and fetch tools to answer: <question>"