A simple Pi search extension that launches runs web searches through SearXNG
README.md

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 an offset parameter).

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 #

  • search and fetch are ordinary tools registered on the session. Any agent (main or sub) with them in its tool set can call them.
  • The bundled web-search preset is a pi-subagent definition with tools: search, fetch and a research-method system prompt: search broadly, fetch primary sources, quote verbatim excerpts, cite every claim, never cite an unfetched page. Launching the subagent tool 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 --tools allowlist activates the matching registered tools, the preset gets search and fetch even 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 subagent tool installed. The search/fetch tools 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:

  1. Built-in defaults
  2. ~/.pi/agent/web-search.json (global)
  3. <project>/.pi/web-search.json (only when the project is trusted)
  4. SEARXNG_BASE_URL environment 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>"