Class: Protege::WebSearchTool

Inherits:
Tool
  • Object
show all
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

Instance Method Details

#use(context:, query:, limit: nil) ⇒ Protege::Result

Run the search and return the matching pages.

Parameters:

Returns:

  • (Protege::Result)

    success carrying query, count, and results, or a failure (blank query, non-2xx, or transport error)



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.message}")
end