Class: Protege::WebSearchTool
- Inherits:
-
Tool
- Object
- Tool
- Protege::WebSearchTool
- Defined in:
- app/tools/protege/web_search_tool.rb
Overview
Built-in web-search tool — the way an agent finds pages on the open web. Subclasses
Protege::Tool, so the harness publishes it in the LLM's tool catalog (id :web_search); when
the model emits a web_search call, the harness routes the arguments to #use.
It is a keyless, best-effort search: it scrapes DuckDuckGo's HTML endpoint and parses the results
page into a list of {title, url, snippet} the agent can reason over and then web_fetch. Because
it scrapes an unofficial endpoint, it can change or be rate-limited — that trade-off buys a search
that needs no API key and is safe to expose to every persona. Richer or keyed search (Tavily,
Perplexity, Brave, …) belongs in a host-app tool, keyed from the host's own config.
Constant Summary collapse
- DEFAULT_LIMIT =
Result count when the caller does not specify a
limit. 5- MAX_LIMIT =
Absolute ceiling on the result count, regardless of the requested
limit. 25- ENDPOINT =
DuckDuckGo's HTML results endpoint (no API key required).
'https://html.duckduckgo.com/html/'- OPEN_TIMEOUT =
Connection- and read-timeouts (seconds) for the HTTP request.
5- READ_TIMEOUT =
10
Instance Method Summary collapse
-
#use(context:, query:, limit: nil) ⇒ Protege::Result
Run the search and return the matching pages.
Instance Method Details
#use(context:, query:, limit: nil) ⇒ Protege::Result
Run the search and return the matching pages.
61 62 63 64 65 66 67 68 69 70 71 72 |
# File 'app/tools/protege/web_search_tool.rb', line 61 def use(context:, query:, limit: nil) term = query.to_s.strip return failure(reason: 'query cannot be empty') if term.empty? response = connection.get(ENDPOINT) { |req| req.params['q'] = term } return failure(reason: "web search returned HTTP #{response.status}") unless (200..299).cover?(response.status) results = parse_results(response.body.to_s).first(clamp(limit)) success(query: term, count: results.size, results:) rescue Faraday::Error => e failure(reason: "web search failed: #{e.}") end |