Class: Kward::WebSearch
- Inherits:
-
Object
- Object
- Kward::WebSearch
- Defined in:
- lib/kward/tools/search/web.rb
Overview
Live web-search implementation with provider fallbacks.
Defined Under Namespace
Classes: NetHttpClient, Result, SearchResponse
Constant Summary collapse
- DEFAULT_MAX_RESULTS =
5- MAX_MAX_RESULTS =
20- MAX_QUERIES =
4- MAX_OUTPUT_BYTES =
8 * 1024
- MODEL_PROVIDER_MAX_TOKENS =
512- MAX_ANSWER_CHARS =
2_000- MAX_EXCERPT_CHARS =
300- HTTP_TIMEOUT_SECONDS =
10- DUCKDUCKGO_URL =
"https://html.duckduckgo.com/html/"- EXA_MCP_URL =
"https://mcp.exa.ai/mcp"- EXA_ANSWER_URL =
"https://api.exa.ai/answer"- EXA_SEARCH_URL =
"https://api.exa.ai/search"- PERPLEXITY_API_URL =
"https://api.perplexity.ai/chat/completions"- GEMINI_API_BASE =
"https://generativelanguage.googleapis.com/v1beta"- DEFAULT_GEMINI_MODEL =
"gemini-2.5-flash"- PUBLIC_SEARXNG_INSTANCES =
[ "https://searx.be", "https://search.inetol.net", "https://searx.tiekoetter.com" ].freeze
- PROVIDERS =
%w[auto exa perplexity gemini duckduckgo].freeze
Instance Method Summary collapse
- #available? ⇒ Boolean
-
#initialize(http_client: NetHttpClient.new, searxng_instances: PUBLIC_SEARXNG_INSTANCES, max_output_bytes: MAX_OUTPUT_BYTES, config: nil) ⇒ WebSearch
constructor
Creates an object for web search provider operations.
- #search(args) ⇒ Object
Constructor Details
#initialize(http_client: NetHttpClient.new, searxng_instances: PUBLIC_SEARXNG_INSTANCES, max_output_bytes: MAX_OUTPUT_BYTES, config: nil) ⇒ WebSearch
Creates an object for web search provider operations.
38 39 40 41 42 43 |
# File 'lib/kward/tools/search/web.rb', line 38 def initialize(http_client: NetHttpClient.new, searxng_instances: PUBLIC_SEARXNG_INSTANCES, max_output_bytes: MAX_OUTPUT_BYTES, config: nil) @http_client = http_client @searxng_instances = searxng_instances @max_output_bytes = max_output_bytes @config = config end |
Instance Method Details
#available? ⇒ Boolean
45 46 47 48 49 50 |
# File 'lib/kward/tools/search/web.rb', line 45 def available? enabled = boolean_config_value("enabled") return enabled unless enabled.nil? true end |
#search(args) ⇒ Object
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
# File 'lib/kward/tools/search/web.rb', line 52 def search(args) queries = args_value(args, "queries") return "Error: queries must be an array with 1-#{MAX_QUERIES} strings" unless valid_queries?(queries) max_results = bounded_max_results(args_value(args, "max_results") || args_value(args, "num_results")) provider = normalize_provider(args_value(args, "provider") || config_value("provider") || "auto") return "Error: provider must be one of: #{PROVIDERS.join(", ")}" unless provider = { max_results: max_results, recency_filter: normalize_recency(args_value(args, "recency_filter") || args_value(args, "recencyFilter")), domain_filter: normalize_domain_filter(args_value(args, "domain_filter") || args_value(args, "domainFilter")), provider: provider } sections = ["# Web search"] failures = [] any_results = false queries.each do |query| response, error = search_query(query, ) any_results = true if successful_response?(response) failures << "#{query}: #{error}" if error && !successful_response?(response) sections << format_query_results(query, response, error) end unless any_results return "Error: web_search found no results\n#{failures.map { |failure| "- #{failure}" }.join("\n")}".strip end truncate_output(sections.join("\n\n")) end |