@zhcsyncer/pi-search-hub

Unified web_search and web_read tools for the Pi coding agent.

Packages

Package details

extension

Install @zhcsyncer/pi-search-hub from npm and Pi will load the resources declared by the package manifest.

$ pi install npm:@zhcsyncer/pi-search-hub
Package
@zhcsyncer/pi-search-hub
Version
1.0.0
Published
Sep 21, 2026
Downloads
156/mo · 3/wk
Author
zhcsyncer
License
MIT
Types
extension
Size
224.1 KB
Dependencies
1 dependency · 3 peers
Pi manifest JSON
{
  "extensions": [
    "./extensions/search-hub.ts"
  ]
}

Security note

Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.

README

pi-search-hub

简体中文

A Search Hub fork for the Pi coding agent. It provides unified web_search and web_read tools across multiple search and content-reading backends.

This package is also included in @zhcsyncer/pi-extensions.

Install

pi install npm:@zhcsyncer/pi-search-hub

Or install the whole extension bundle:

pi install npm:@zhcsyncer/pi-extensions

Tools

web_search

Searches the web through configured routing. Enabled backends are tried in order and the first success stops the call. combine=true is model-only (default off) and merges up to three usable sources, with each result tagged by source. Configuration cannot force combine on every call.

Important call options include:

  • query — natural-language search query;
  • numResults — requested result count from 1 to 20;
  • combine — merge several enabled providers for the same query (default false);
  • compact — return title-source-URL lines instead of verbose search content.

Supported search backends are Exa, Tavily, Firecrawl, Parallel, OpenAI Codex, and Grok. Firecrawl is the keyless fallback when no backend is explicitly enabled. Exa, Tavily, and Parallel require an API key. Codex and Grok use Pi /login (hosted web search on the provider's inference API) and do not store keys in Search Hub config. If a hosted backend hits a subscription usage limit, it is skipped for 5 hours. Routing is priority (an ordered enabled list), random, or best-latency.

web_read

Fetches a URL and returns extracted Markdown. Readers are tried in order: Firecrawl, then Exa, then Parallel. They fail over sequentially and are never queried or merged in parallel. Firecrawl is keyless; Exa and Parallel need a key.

Important call options include:

  • url — page URL.

Tool rows

Search Hub draws its own Claude-style rows. It does not use pi-tool-display-intent.

  • call lines show ● Web Search("query") or ● Read Web Page(url) instead of generic (N args) text;
  • result lines show backend, result count, fallback, or extracted size.

Semantic call metadata includes:

Tool Target Metadata
web_search Search query Combine, result limit, compact mode
web_read Shortened URL Starting reader

Search and read progress is emitted through the active tool call rather than a persistent footer status. Semantic result status includes:

Tool Status
web_search Actual backend, result count, fallback state, and usable/attempted backend health for combined searches
web_read Actual reader, extracted character count, and whether display content was truncated to the 10k-character presentation limit

Verbose search output still begins with a raw ## Search Results: header in the model-facing result.

Search Hub still owns the content sent to the model, including backend selection, result quantity, compact result generation, and backend-level truncation. The web_search.compact argument changes the tool result itself, not only the TUI row.

Configuration

Search Hub reads configuration from:

  1. $PI_CODING_AGENT_DIR/extension-data/pi-search-hub/config.json for global settings;
  2. .pi/extension-data/pi-search-hub/config.json in a trusted current project.

Trusted project settings win. Backend maps are merged per backend, so a project can override one backend without repeating every global entry. Untrusted projects are never probed for Search Hub configuration. Configuration is refreshed during use; interactive edits stay in a draft until you press s.

Configuration, credential and Exa usage warnings appear as deduplicated Pi notifications instead of raw terminal output. Repeated search or read failures for the same backend also raise a warning. Those local outcomes are not used as remaining quota. Successful tool results also retain warnings in their details, including in headless runs. Ordinary provider failures continue through the existing tool-error and fallback paths.

On first use, Search Hub automatically migrates the previous global and trusted-project paths, upgrades recognized settings, drops unmappable fields with a warning, and removes the old file only after the new file passes a semantic round trip. Exa usage state similarly moves to $PI_CODING_AGENT_DIR/extension-data/pi-search-hub/state/exa-usage.json with serialized atomic updates.

Interactive setup

Run /search-hub setup to edit global routing and compact output. /search-hub status shows the local quota ledger (Tavily/Firecrawl remaining, skipped keys and unlock times) without fetching on open. Press r or run /search-hub status refresh to update Tavily/Firecrawl usage. Provider switches, keys, and Codex/Grok models are on a second page. When routing is priority, the enabled try order is a separate list: pick with Enter, move with up/down.

Edits stay in a draft. s saves; Esc closes immediately when clean. A dirty Esc asks once whether to discard or keep editing, and does not offer save in that prompt. Keys are edited in ui.editor, one reference per line, and are written only on save. Disabling a backend keeps stored keys. A trusted project config can still override the global file; setup only hints at that and does not edit the project file.

Minimal example:

{
  "routing": "priority",
  "priority": ["exa", "firecrawl"],
  "backends": {
    "exa": { "enabled": true, "apiKeys": ["EXA_API_KEY"] },
    "firecrawl": { "enabled": true }
  }
}

Copy search.json.example for a complete backend matrix. Credentials may be environment-variable names such as EXA_API_KEY, shell commands prefixed with !, or key values saved directly in apiKeys. Prefer environment variables or a secret manager, and never commit credentials. A legacy apiKey string is migrated into apiKeys on save. Multiple keys rotate only after 429, 402, 432, or quota exhaustion.

See UPSTREAM_README.md for the upstream backend-specific reference. Local behavior described in this README takes precedence for the bundled fork.

Upstream source

The exact source provenance is recorded in UPSTREAM_SOURCE.md.

Development

pnpm --filter @zhcsyncer/pi-search-hub check
pi --no-extensions -e ./packages/pi-search-hub --list-models __pi_search_hub_check__

License

The upstream package.json and README declare MIT, but the v2.8.0 tag does not contain a standalone license file. See UPSTREAM_NOTICE.md for the preserved notice and LICENSE for this fork's combined terms.