diff --git a/packages/binary-file-guard/README.md b/packages/binary-file-guard/README.md index c9afd17..45872a6 100644 --- a/packages/binary-file-guard/README.md +++ b/packages/binary-file-guard/README.md @@ -9,8 +9,11 @@ conversion + `pdftotext` for Office documents. ## What is blocked -PDFs, archives (ZIP, tar, gzip, 7z, RAR, etc.), executables (ELF, PE), databases -(SQLite), audio, video, and more; all detected via magic bytes. +PDFs, archives (ZIP, tar, gzip, bzip2, xz, zstd, LZ4, 7z, RAR, RPM, CPIO), +executables (ELF, PE, Java serialized objects), databases (SQLite), audio, +video, and more. Known formats are matched by magic-byte signatures; files +that match no signature but still look binary (high null-byte or invalid-UTF-8 +ratio) are blocked too. Supported image formats (PNG, JPEG, GIF, WebP) are not blocked; the LLM can view them directly. Unsupported image formats (AVIF, HEIC, BMP, ICO) are blocked with conversion hints. diff --git a/packages/binary-file-guard/package.json b/packages/binary-file-guard/package.json index 818a0bb..ac119f7 100644 --- a/packages/binary-file-guard/package.json +++ b/packages/binary-file-guard/package.json @@ -1,7 +1,7 @@ { "name": "@m4ss/pi-binary-file-guard", "version": "0.1.0", - "description": "Block read tool from reading binary files (PDF, archives, executables) by detecting magic bytes", + "description": "Block Pi's read tool from loading binary files (PDFs, archives, executables, databases) and suggest the right CLI tool to extract their contents instead", "license": "MIT", "author": "Paolo Barbolini ", "repository": { diff --git a/packages/llms-txt/README.md b/packages/llms-txt/README.md index 2408d39..b66d1d2 100644 --- a/packages/llms-txt/README.md +++ b/packages/llms-txt/README.md @@ -1,13 +1,10 @@ # @m4ss/pi-llms-txt -We built this to let the model discover a site's structure before diving into -individual pages. It fetches and caches `llms.txt` from documentation sites -using a cache-first strategy. - -The [`llms.txt`](https://llmstxt.org) standard is a curated, LLM-friendly map of a -website's most important content. Not many sites publish one yet, but when they do, -this extension gives the model a site map before it starts fetching pages. For sites -that don't publish `llms.txt`, the tool reports it and moves on. +Fetch and cache a site's [`llms.txt`](https://llmstxt.org), a curated LLM-friendly +map of a website's most important content, so the model can survey a documentation +site's structure before deep-fetching individual pages. Few sites publish one yet; +when a site doesn't, the tool reports that and moves on. Cache-first, so repeat +lookups are cheap. ## Notes @@ -23,8 +20,6 @@ pi install npm:@m4ss/pi-llms-txt ## Usage -The LLM calls `llms_txt` on its own. You can also invoke it directly: - ``` llms_txt("www.postgresql.org") llms_txt("redis.io", forceRefresh=true) diff --git a/packages/llms-txt/package.json b/packages/llms-txt/package.json index ac7ee24..eb398c2 100644 --- a/packages/llms-txt/package.json +++ b/packages/llms-txt/package.json @@ -1,7 +1,7 @@ { "name": "@m4ss/pi-llms-txt", "version": "0.1.0", - "description": "llms.txt cache-first tool — fetch and cache llms.txt from any domain, inject guidance so the model uses it before deep-fetching docs", + "description": "Cache-first llms.txt tool for Pi: fetches and caches a site's llms.txt map so the model can survey important pages before deep-fetching individual docs", "license": "MIT", "author": "Paolo Barbolini ", "repository": { diff --git a/packages/llms-txt/src/index.ts b/packages/llms-txt/src/index.ts index 85e9127..986e113 100644 --- a/packages/llms-txt/src/index.ts +++ b/packages/llms-txt/src/index.ts @@ -113,14 +113,14 @@ export default function (pi: ExtensionAPI) { name: "llms_txt", label: "llms.txt", description: - "Fetch a domain's llms.txt — a curated map of the site's documentation. " + + "Fetch a domain's llms.txt, a curated map of the site's documentation. " + "Use before deep-fetching docs sites. Skip for blogs, news, or single-page lookups.", promptSnippet: "Fetch and cache llms.txt from any domain for LLM-friendly documentation maps", promptGuidelines: [ - "Use llms_txt(domain) to fetch a domain's llms.txt — a curated map of its documentation — before deep-fetching individual pages.", + "Use llms_txt(domain) to fetch a domain's llms.txt, a curated map of its documentation, before deep-fetching individual pages.", "Skip llms_txt for blogs, news, or single-page lookups; use web_fetch directly.", - "Use llms_txt forceRefresh sparingly — only when the cached map may be stale.", + "Use llms_txt forceRefresh sparingly, only when the cached map may be stale.", ], parameters: LlmsTxtParams, diff --git a/packages/search-delegator/README.md b/packages/search-delegator/README.md index a586910..99be8df 100644 --- a/packages/search-delegator/README.md +++ b/packages/search-delegator/README.md @@ -49,15 +49,16 @@ Config file: `~/.pi/agent/search-delegator.json` (missing fields fall back to de | `blocked_tools` | `["staan_search", "web_fetch", "llms_txt"]` | Tool names removed from the main model and granted to the searcher | | `searcher_subagent_name` | `"searcher"` | Subagent name (must match the `.md`) | | `searcher_model` | `""` | Model for the searcher (`provider/model`). Empty = inherit parent's default. Set a cheap model to keep web research inexpensive | +| `orchestrator_prompt` | _(built-in web-research guidance)_ | Text sent to the main model at session start, telling it how to delegate to the searcher | The `searcher.md` template is regenerated whenever the config changes. If you edit `searcher.md` by hand, your version is detected and left untouched. ### Tightening the searcher -`searcher.md` restricts the child to the tools listed in `blocked_tools` (by default -`tools: staan_search, web_fetch, llms_txt`). To narrow it further, edit -`~/.pi/agent/agents/searcher.md`, but keep whatever extensions provide those tools loaded. +`~/.pi/agent/agents/searcher.md` restricts the child to the tools listed in `blocked_tools` (by default +`tools: staan_search, web_fetch, llms_txt`). To narrow it further, edit that file, +but keep whatever extensions provide those tools loaded. ## License diff --git a/packages/search-delegator/package.json b/packages/search-delegator/package.json index c2d0bc9..a42ac7a 100644 --- a/packages/search-delegator/package.json +++ b/packages/search-delegator/package.json @@ -1,7 +1,7 @@ { "name": "@m4ss/pi-search-delegator", "version": "0.1.0", - "description": "Block web search/fetch/llms_txt tools on the main pi model and force delegation to a searcher subagent", + "description": "Keep Pi's main context clean: remove web search, fetch, and llms_txt tools from the main model and force delegation to a focused, cheaper searcher subagent", "license": "MIT", "author": "Paolo Barbolini ", "repository": { diff --git a/packages/search-delegator/src/config.ts b/packages/search-delegator/src/config.ts index 9346d09..64b68ae 100644 --- a/packages/search-delegator/src/config.ts +++ b/packages/search-delegator/src/config.ts @@ -28,9 +28,10 @@ const DEFAULT_ORCHESTRATOR_PROMPT = [ "", ' subagent({ agent: "searcher", task: "" })', "", - 'Write specific tasks — e.g. "Find latest stable Diesel version; return version,', - 'date, source URL." The searcher returns compact findings with URLs. Cite those', - "URLs. Batch related lookups into one delegation.", + 'Write specific tasks. For example: "Research how SvelteKit load functions', + "interact with caching and invalidation: cover fetch caching, depends(), and", + 'invalidate(). Return a summary with source URLs." The searcher returns compact', + "findings with URLs. Cite those URLs. Batch related lookups into one delegation.", ].join("\n"); export const DEFAULT_CONFIG: Config = { diff --git a/packages/search-delegator/src/searcher-template.ts b/packages/search-delegator/src/searcher-template.ts index 909ba4a..7984344 100644 --- a/packages/search-delegator/src/searcher-template.ts +++ b/packages/search-delegator/src/searcher-template.ts @@ -63,7 +63,7 @@ function renderTemplate(config: Config): string { const front = [ "---", `name: ${config.searcher_subagent_name}`, - "description: Web research specialist — searches the web, fetches pages, and explores docs sites; returns compact findings with source URLs", + "description: Web research specialist: searches the web, fetches pages, and explores docs sites; returns compact findings with source URLs", `tools: ${grantedTools.join(", ")}`, ]; if (config.searcher_model.trim()) { @@ -75,9 +75,9 @@ function renderTemplate(config: Config): string { "You are a focused web research agent. Return compact, sourced answers.", "", "## Tools", - "- `staan_search` — discover information, find URLs. Use `site:domain` or `-domain` to narrow. For known URLs, use `web_fetch` directly.", - "- `web_fetch` — retrieve a known URL's content as Markdown. Prefer raw/API endpoints over HTML. To discover URLs, use `staan_search` first.", - "- `llms_txt` — map a docs site's structure before fetching individual pages. Skip for blogs/news.", + "- `staan_search`: discover information, find URLs. Use `site:domain` or `-domain` to narrow. For known URLs, use `web_fetch` directly.", + "- `web_fetch`: retrieve a known URL's content as Markdown. Prefer raw/API endpoints over HTML. To discover URLs, use `staan_search` first.", + "- `llms_txt`: map a docs site's structure before fetching individual pages. Skip for blogs/news.", "", "## Rules", "- Prefer official docs, registries, and primary sources.", diff --git a/packages/staan-search/README.md b/packages/staan-search/README.md index 6c0895b..8da5874 100644 --- a/packages/staan-search/README.md +++ b/packages/staan-search/README.md @@ -6,7 +6,7 @@ model can search the web and get enriched result chunks. ## Features -- Web and news search with semantic enrichment (extra snippets for RAG-style usage) +- Web and news search, with semantic enrichment (extra snippets for RAG-style usage) - Domain filters via `site:domain` or `-domain.tld` in the query - Market selection for language/region-aware results (default: `fr-fr`) - Full-content requests that ask Staan for page bodies and reranking @@ -19,40 +19,31 @@ pi install npm:@m4ss/pi-staan-search ## Usage -Set your API key: +Requires `STAAN_API_KEY`: ```bash export STAAN_API_KEY='your_staan_api_key' ``` -The LLM will automatically see `staan_search` as an available tool. Example calls: - -- `staan_search("GDPR NIS2 Europe")` – Web Search for AI using the default `fr-fr` market -- `staan_search("AI Act", type="news")` – plain news search -- `staan_search("site:redis.io transactions")` – narrow to a specific domain -- `staan_search("PostgreSQL performance", minScore=0.2, maxSnippets=5)` – RAG-ready chunks +``` +staan_search("GDPR NIS2 Europe") +staan_search("AI Act", type="news") +staan_search("site:redis.io transactions") +staan_search("PostgreSQL performance", minScore=0.2, maxSnippets=5) +``` ## API Key -Get a key at [staan.ai](https://staan.ai) → Developer Console. +Get a key at the [Staan console](https://staan.ai/console). - Free tier: 1,000 requests/month - Web Search: €1 / 1,000 requests - Web Search for AI: €2 / 1,000 requests -## Routing, privacy, and fallback behavior - -- `fr-fr` (default) prefers the European/Staan-backed route. -- `en-us` may use fallback/non-EU infrastructure and domain filters (`site:`) may not work on fallback-routed markets. -- For compliance-sensitive use, verify Staan's DPA/subprocessors and request EU-only routing. - ## Limits - Queries are capped at 400 characters (API limit). A note is added if truncated. -- Domain filters via `site:` syntax may not work when Staan routes through its fallback provider; use `market="fr-fr"` for reliable filtering. -- Pagination supports offsets of 0, 10, 20, or 30 (10 results per page). -- Web searches use semantic enrichment by default. Set `extraSnippets=false` for plain Web Search. -- All API calls use a 10s timeout. +- Domain filters via `site:` syntax may not work when Staan routes through its fallback provider; `market="fr-fr"` filters reliably. ## Related packages diff --git a/packages/staan-search/package.json b/packages/staan-search/package.json index 6c817b5..dc2a18c 100644 --- a/packages/staan-search/package.json +++ b/packages/staan-search/package.json @@ -1,7 +1,7 @@ { "name": "@m4ss/pi-staan-search", "version": "0.1.0", - "description": "Staan AI European search extension for pi-coding-agent", + "description": "Web-search tool for Pi powered by Staan AI's European search API, with semantically enriched snippets for RAG-style usage, news search, and domain filtering", "license": "MIT", "author": "Paolo Barbolini ", "repository": { diff --git a/packages/staan-search/src/index.ts b/packages/staan-search/src/index.ts index c236fe4..0a4e2c6 100644 --- a/packages/staan-search/src/index.ts +++ b/packages/staan-search/src/index.ts @@ -132,7 +132,7 @@ export default function (pi: ExtensionAPI) { "Use site:domain or -domain in the query to narrow results to or from specific sites.", 'Keep the default market="fr-fr" for the European route; use market="en-us" only for US-specific needs.', "Treat snippets as pointers, not proof: verify claims against the enriched chunks or a web_fetch of the page before relying on them.", - "To look up a known package or repo, fetch its registry/API endpoint instead of searching (bare names collide); search only to disambiguate.", + "When you already know the URL or identifier, fetch it directly. Search to discover unknowns or disambiguate colliding names (e.g. bare package names).", ], parameters: SearchParams, diff --git a/packages/web-fetch/README.md b/packages/web-fetch/README.md index 56c918a..dcd7ea6 100644 --- a/packages/web-fetch/README.md +++ b/packages/web-fetch/README.md @@ -7,7 +7,7 @@ caps response size to keep things manageable. ## Features - Fetches any HTTP/HTTPS URL and converts HTML to clean Markdown (JSON is pretty-printed) -- Blocks private network addresses (localhost, RFC 1918, link-local); every redirect hop is validated, so a redirect can't bounce into an internal address +- Blocks private network addresses (localhost, RFC 1918, link-local, CGNAT, IPv6 ULA); every redirect hop is validated, so a redirect can't bounce into an internal address - Follows instant meta-refresh redirects (the stub pages static site generators emit) - 10s default timeout, overrideable per call; large responses capped at 5MB @@ -28,10 +28,10 @@ web_fetch(url="https://example.com/slow", timeoutMs=20000) ## Private networks -Blocks private/internal addresses (localhost, RFC 1918, link-local) on all redirect hops (max 5, each validated). +Blocks private/internal addresses (localhost, RFC 1918, link-local, CGNAT, IPv6 ULA) on all redirect hops (max 5, each validated). The check runs on the URL's hostname, so it does not defend against DNS -rebinding — a hostile public hostname that resolves to a private address gets +rebinding: a hostile public hostname that resolves to a private address gets through (that would require a pinned resolver). Treat the guard as protection against accidental internal access, not as a hard security boundary; don't rely on it to isolate a machine that can reach sensitive internal services. diff --git a/packages/web-fetch/package.json b/packages/web-fetch/package.json index ac08fc5..5d5a3d4 100644 --- a/packages/web-fetch/package.json +++ b/packages/web-fetch/package.json @@ -1,7 +1,7 @@ { "name": "@m4ss/pi-web-fetch", "version": "0.1.0", - "description": "Web fetch (HTML→Markdown) tool for pi-coding-agent", + "description": "Web-fetch tool for Pi: fetches HTTP(S) URLs, converts HTML to clean Markdown, and pretty-prints JSON responses", "license": "MIT", "author": "Paolo Barbolini ", "repository": { diff --git a/packages/web-fetch/src/index.ts b/packages/web-fetch/src/index.ts index 9ae725c..373f67b 100644 --- a/packages/web-fetch/src/index.ts +++ b/packages/web-fetch/src/index.ts @@ -64,7 +64,7 @@ export default function (pi: ExtensionAPI) { "Prefer raw/API endpoints over rendered HTML. To discover URLs, use staan_search first.", promptSnippet: "Fetch and convert a web page to Markdown", promptGuidelines: [ - "Use web_fetch to retrieve any HTTP/HTTPS URL — whether the user gave it, you already know it, or staan_search returned it — and cite the fetched URL in your answer.", + "Use web_fetch to retrieve any HTTP/HTTPS URL, whether the user gave it, you already know it, or staan_search returned it, and cite the fetched URL in your answer.", "Prefer official structured APIs, raw file URLs, or export endpoints over rendered HTML when they carry the same content; for GitHub use raw.githubusercontent.com (file contents) and the GitHub API (repo metadata).", "When you know a package or repo name, fetch its registry/API endpoint directly (crates.io, npm, PyPI, GitHub API), choosing the most specific resource to avoid pulling unneeded data.", "Fetch rendered HTML only when presentation matters or no structured/raw endpoint exists; keep the default format=markdown and use html only when you need raw markup.",