Files
discord_bot/specs/SPEC-015-websearch.md
T

2.0 KiB

SPEC-015 — Web search (Exa)

A web_search function tool for general "look it up on the internet" questions the other tools do not cover: IGDB is games, the Codex is Adeptus Mechanicus lore, the news store is the configured feeds, and fetch_url needs a URL the user already has. Web search fills the gap and pairs with fetch_url (search → pick a link → read it). Results are external text and are sanitized (SAF-03); the Exa key is a host secret, never in the repo. Active only when enable-web-search = true and a key is present.

WEB-01 — web_search is offered as a tool (coverage: test)

When enable-web-search is true and an Exa key is available (exa-api-key in config, else EXA_API_KEY env), the chat call's tools list includes a web_search function (query string, optional num_results). With the flag off or no key it is absent.

WEB-02 — Results are reduced and sanitized (coverage: test)

Each Exa result becomes {title, url, snippet, published}; title and snippet pass through sanitize_external_text (snippet capped at web-snippet-chars, default 400) so a web page can neither inject an @everyone nor smuggle control characters into the prompt.

WEB-03 — Result count is bounded (coverage: test)

num_results is clamped to 1..MAX_RESULTS (10) before the request, so neither a huge fan-out nor a zero/negative count reaches the API.

WEB-04 — Missing key and API failure are reported, not raised (coverage: test)

With no key the tool returns an {error: ...} result without a network call. A request that raises (network, non-2xx, bad JSON) is logged and returns an {error: ...} dict — search never raises into the loop.

WEB-05 — Searches are metered per user (coverage: test)

Each web_search increments a per-user daily counter; over web-daily-per-user (default 30) the tool refuses with an error result without calling the API. The budget gate (SAF-04) still applies to the surrounding model calls.