issue-282: add searxng extension #283
No reviewers
Labels
No labels
bug
chore
documentation
enhancement
feature
ready
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
david/pi-extensions-and-skills!283
Loading…
Reference in a new issue
No description provided.
Delete branch "feature/issue-282/add-searxng-extension"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Closes #282
What
Adds a
searxngextension registering one tool,web_search, backed by a self-hosted SearXNG metasearch instance.src/env.tsSEARXNG_URL, read fresh per call so/reloadpicks up a change; defaults tohttp://localhost:8888src/client.tssearxngRequest— always forcesformat=json, raisesHttpErrorwith status and body on non-2xxsrc/defaults.tssrc/errors.tsHttpErrorsrc/tools/search.tsweb_searchtool: params, caps,ToolErrormappingdocker-compose.yml,config/settings.ymlREADME.md(extension + root)package.jsonWhy
The other network-backed extensions here (
victorialogs,mongodb,vision) each wrap one external service behind a small tool surface. Web search was the gap — there was no way to find a page before reading it withfetch/read.Self-hosting keeps queries off third-party search APIs and avoids per-call billing. The cost is running a container, which is why the compose file ships alongside.
Three decisions worth calling out:
config/settings.ymlis required, not a convenience. A stock SearXNG shipssearch.formatsashtmlonly and enablesserver.limiterbot detection. Both answerformat=jsonwith a bare403, so an unconfigured instance fails 100% of calls. The file setsuse_default_settings: trueand overrides nothing else, so an image bump still inherits the upstream engine list without a merge.The response is reduced to title, URL, snippet and the engines that ranked the URL. The rest of the payload is scoring and template data the model can't act on, and it's a large fraction of the bytes.
details.unresponsiveEnginesis surfaced because a failed upstream engine is usually why a result set is thinner than expected.How tested
bun testinextensions/searxng/— 43 pass, 0 fail, acrossclient,defaults,env,errorsandtools/search. Fetch is stubbed, so no live instance is needed and the suite is hermetic.Coverage targets the failure modes, not just the happy path:
format=jsonis sent regardless of caller inputcategories,engines,language,time_range) forwarded when supplied, omitted when nottotalBeforeLimitreporting the pre-limit count403raises aToolErrornaming thesettings.ymlfix — the single most likely setup errorToolErrorasking whether the container is runninganswersaccepted as bare strings or objects, both of which SearXNG has shippedunresponsive_enginesshapes parsedAlso verified live against a running local instance during development.
Out of scope notes
.envis not committed — excluded by the root.gitignoreand confirmed withgit add --dry-runbefore staging..env.examplecarries theSEARXNG_SECRETplaceholder and theopenssl rand -hex 32command.testscript is unchanged. These are bun tests and the script isnode --test;victorialogssits outside it for the same reason. Folding both in is a separate change rather than a drive-by here.