@zhcsyncer/pi-search-hub
Unified web_search and web_read tools for the Pi coding agent.
Package details
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:
$PI_CODING_AGENT_DIR/extension-data/pi-search-hub/config.jsonfor global settings;.pi/extension-data/pi-search-hub/config.jsonin 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
- Repository:
ronnieops/pi-search-hub - Baseline:
v2.8.0/96ccf692123d35a3cf4b615d597a80fe9e9f6229 - Preserved documentation:
UPSTREAM_README.md - Preserved release history:
UPSTREAM_CHANGELOG.md
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.