feat(tools): add Exa + Tavily web search providers with ranked ordering

Port Exa and Tavily provider clients from PR #825 into the tenant-aware
overlay architecture (builtin_tool_tenant_configs.settings).

- Add ExaConfig + TavilyConfig to WebToolsConfig with provider_order
- Add Exa HTTP client (api.exa.ai/search, x-api-key auth)
- Add Tavily HTTP client (api.tavily.com/search, Bearer auth)
- Extend Brave + DDG constructors with per-provider maxResults
- Add config_secrets plumbing for exa/tavily API keys (apply/collect/mask/strip)
- Refactor gateway_setup.go to use WebSearchConfigFromConfig
- Add NormalizeWebSearchProviderOrder (DDG always last, dedup, unknown skip)
- Extract web_search_config.go (builder, normalizer, shared helpers)
- 11 new unit tests for provider order, builder, clamp, normalize

Credit: @kaitranntt (PR #825) for the original Exa + Tavily implementation.
This commit is contained in:
viettranx committed 2026-04-12 11:09:32 +07:00
1 parent 7ae9721c2b
commit 30a40bbe59
10 files changed
+527 -44

No files matched your search

+1 -5
View File
@@ -116,11 +116,7 @@ func setupToolRegistry(
}
// Web tools (web_search + web_fetch)
webSearchTool := tools.NewWebSearchTool(tools.WebSearchConfig{
BraveEnabled: cfg.Tools.Web.Brave.Enabled,
BraveAPIKey: cfg.Tools.Web.Brave.APIKey,
DDGEnabled: cfg.Tools.Web.DuckDuckGo.Enabled,
})
webSearchTool := tools.NewWebSearchTool(tools.WebSearchConfigFromConfig(cfg))
if webSearchTool != nil {
toolsReg.Register(webSearchTool)
slog.Info("web_search tool enabled")