@boti-ormandi/pi-web
Native web search and secure public-URL fetch tools for pi using pi-managed OpenAI Codex or Anthropic subscription OAuth.
Package details
Install @boti-ormandi/pi-web from npm and Pi will load the resources declared by the package manifest.
$ pi install npm:@boti-ormandi/pi-web- Package
@boti-ormandi/pi-web- Version
0.4.1- Published
- Jul 22, 2026
- Downloads
- 239/mo · 176/wk
- Author
- boti-ormandi
- License
- MIT
- Types
- extension
- Size
- 161 KB
- Dependencies
- 6 dependencies · 4 peers
Pi manifest JSON
{
"extensions": [
"./src/index.ts"
]
}Security note
Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.
README
pi-web
Native web_search and secure public-URL web_fetch tools for the
pi coding agent.
pi-web reuses the subscription OAuth sessions already managed by pi:
- OpenAI Codex through the
openai-codexprovider. - Anthropic Claude through the
anthropicprovider.
It does not read credential files, accept API keys, register replacement providers, or fall back to environment credentials. Model-backed requests are sent only to the fixed first-party provider origins after the active canonical model and OAuth snapshot have passed strict trust checks.
Requirements
- Node.js
>=22.19.0. - pi
>=0.80.10. - A pi-managed OAuth login for any model-backed provider route you select.
A no-prompt local fetch can work without either provider being logged in.
Install
Install from npm through pi:
pi install npm:@boti-ormandi/pi-web
For local development, point pi at a checkout:
{
"extensions": ["/absolute/path/to/pi-web"]
}
Place that in ~/.pi/agent/settings.json or a project's .pi/settings.json,
then reload or restart pi.
Tools
web_search
Searches the public web through one subscription provider route.
{
query: string;
provider?: "openai-codex" | "anthropic";
allowed_domains?: string[];
blocked_domains?: string[];
}
Rules:
querymust contain at least two characters.provideris optional. The literal valueautois not accepted in tool JSON; omit the field to use configured or automatic routing.allowed_domainsandblocked_domainsare mutually exclusive after empty arrays are normalized away.- Domain entries must be lowercase IDNA hostnames. Schemes, credentials, paths, ports, wildcards, and IP literals are rejected.
- A domain filter matches the named domain and its subdomains.
- URL is the only guaranteed source field. Title and snippet are optional.
Filtered searches fail closed: pi-web requires structured public source URLs, verifies every source against the requested filter, and omits unverified provider prose. Unfiltered searches may return useful provider text even when no structured sources are present.
web_fetch
Retrieves one public HTTP(S) URL. With no prompt, it returns bounded retrieved text. With a prompt, it processes only verified retrieved content.
{
url: string;
prompt?: string;
provider?: "openai-codex" | "anthropic";
}
prompt is trimmed. Empty or whitespace-only prompts are treated as omitted
and never trigger subscription processing.
Returned metadata can include the final URL, title, content kind, PDF page count, and explicit source/input/answer truncation flags. Model IDs, costs, cache state, account metadata, encrypted provider state, and native response references are not stable tool details.
Routing
Provider precedence for model-backed work is:
- The tool's explicit
provider. - The global config provider when it is not
auto. - The automatic candidate sequence resolved for the current invocation.
Explicit selection is strict. Automatic routing may advance to another provider only after a pre-semantic resolution, OAuth, catalog, or capability failure. Once native search, native open, or grounded processing is dispatched, that provider owns the result or error; pi-web never switches providers after semantic commitment.
Search and prompted fetch
| Active trusted OAuth model | Automatic candidate order |
|---|---|
| OpenAI Codex | Active Codex, then inactive Anthropic |
| Anthropic | Active Anthropic, then inactive Codex |
| Neither | Inactive Codex, then inactive Anthropic |
The active model is observed on every tool invocation. Active trusted models are used directly rather than replaced by a catalog choice.
No-prompt fetch
No-prompt retrieval intentionally has a different algorithm:
- Explicit/configured Codex: resolve Codex OAuth, perform native open, and require retrieval proof.
- Explicit/configured Anthropic: retrieve locally. No Anthropic auth lookup or Anthropic request occurs.
- Automatic: use native Codex only when the active model is trusted Codex with an OAuth snapshot; otherwise retrieve locally immediately.
No-prompt fetch never performs inactive-provider fallback.
Provider behavior
OpenAI Codex
- Search uses the fixed ChatGPT Codex native search endpoint.
- An active trusted Codex model is used directly.
- Inactive Codex selection performs a fresh fixed-protocol catalog preflight, then chooses an exact trusted pi model deterministically.
- Fetch uses native open. Prompted fetch requires native retrieval proof before a separate ordinary Codex processing request.
- The processing request uses the same model and receives only bounded retrieved text plus the normalized prompt.
Anthropic
- Search uses Anthropic's native server-side web search tool through the accepted subscription compatibility envelope.
- The active trusted Anthropic model is used directly. Inactive fallback is the
exact trusted
claude-haiku-4-5model when present. - Fetch retrieval is local. Prompted fetch retrieves and extracts first, then performs ordinary grounded Anthropic processing.
- Retrieval or extraction failure occurs before OAuth resolution and makes no Anthropic request.
- No-prompt Anthropic fetch is entirely local.
Configuration
pi-web has one durable config file:
~/.pi/agent/extensions/pi-web/config.json
Schema and default:
{
"provider": "auto"
}
Accepted values are auto, openai-codex, and anthropic. provider is the
only permitted key. Missing files and {} resolve to auto; malformed JSON,
extra keys, legacy multi-key configuration, arrays, null, and other
primitives produce an observable configuration error.
There is no project-local pi-web config, environment-variable override, or pi CLI flag.
Public-URL security boundary
Local retrieval uses a one-shot direct-IP HTTP/HTTPS connector rather than a global reusable fetch client.
- Only public
http:andhttps:URLs are accepted. - Credentials, fragments, non-default ports, and private or special-use IP space are rejected.
- Every DNS answer is validated; mixed public/private answers fail closed.
- The connected peer address must match the validated pinned address before a request is sent.
- Original HTTP Host and TLS SNI are preserved while the connection remains pinned to the validated IP.
- Every redirect is re-resolved and revalidated. HTTPS downgrade is rejected.
- Caller-provided headers, proxy routing, compression, connection reuse, and private-address escape switches are not supported.
- Deadlines, redirect count, response bytes, extraction work, provider input, and returned output are bounded.
- Abort signals propagate through network retrieval, HTML extraction, and PDF page processing.
This is a public-web tool, not a local-network browser or authenticated scraper.
/web-status
/web-status is the only slash command added by pi-web. It reports separate
snapshot predictions for:
- Search.
- Prompted fetch.
- No-prompt fetch.
The command may inspect the active model, registry snapshots, OAuth-status snapshots, validated config, and public version information. It does not refresh auth, resolve credentials, contact provider or catalog endpoints, write files, or display credentials, account IDs, or native provider state.
Its output distinguishes active trusted routes, inactive catalog/fallback preflight, local retrieval, and the fact that request-time OAuth is still required.
Output and UI
Collapsed tool rows show the selected route, source/content summary, and any truncation state. Expanded rows show normalized source metadata and bounded previews. Preview clipping is renderer-only: the full bounded tool result is still returned to the agent.
Model-visible output also includes explicit markers when provider text, source lists, retrieved text, grounded-processing input, or the final answer was truncated.
Clean-break migration
Version 0.4.0 replaces the earlier Anthropic-only configurable product with
the strict native OAuth contract above. Removed surfaces include model/tier
controls, alternate fetch backends, generic provider routing, project and
environment configuration layers, caches, citation replay, cost display, and
legacy slash commands.
See CHANGELOG.md for the complete migration table. Legacy cache files, when present, are left untouched and are neither read nor deleted.
Development
npm install
npm run typecheck
npm test
npm run test:package
npm test runs deterministic schema, config, trust, routing, provider,
transport, extraction, status, tool-output, and renderer tests.
npm run test:package packs the exact npm artifact, rejects private or test
material from the tarball, installs it with the minimum and newest tested pi
host packages against TypeBox 1.1.38 and the newest tested stable TypeBox
<2. It loads the extension under Node 22.19.0 and the current Node runtime.
The verification uses isolated temporary homes and does not read the user's pi
credentials or configuration.
Live provider calls are not required for unit, package, or release acceptance. The Codex native protocol has separate completed live evidence; Anthropic uses the accepted historical working baseline and deterministic compatibility fixtures.
License
MIT. See LICENSE.