web search via exa (spec-015): web_search tool, sanitized results, per-user cap, host-config key
This commit is contained in:
@@ -0,0 +1,42 @@
|
||||
# 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.
|
||||
Reference in New Issue
Block a user