feat: add support for DuckDuckGo and refactor Brave search configuration support the control with config.js

This commit is contained in:
Satyam Tiwari
2026-02-13 14:42:55 +05:30
parent fbe1152e2d
commit 2f5849b39d
5 changed files with 77 additions and 22 deletions

View File

@@ -63,8 +63,15 @@ func NewAgentLoop(cfg *config.Config, msgBus *bus.MessageBus, provider providers
toolsRegistry.Register(tools.NewListDirTool(workspace, restrict))
toolsRegistry.Register(tools.NewExecTool(workspace, restrict))
braveAPIKey := cfg.Tools.Web.Search.APIKey
toolsRegistry.Register(tools.NewWebSearchTool(braveAPIKey, cfg.Tools.Web.Search.MaxResults))
if searchTool := tools.NewWebSearchTool(tools.WebSearchToolOptions{
BraveAPIKey: cfg.Tools.Web.Brave.APIKey,
BraveMaxResults: cfg.Tools.Web.Brave.MaxResults,
BraveEnabled: cfg.Tools.Web.Brave.Enabled,
DuckDuckGoMaxResults: cfg.Tools.Web.DuckDuckGo.MaxResults,
DuckDuckGoEnabled: cfg.Tools.Web.DuckDuckGo.Enabled,
}); searchTool != nil {
toolsRegistry.Register(searchTool)
}
toolsRegistry.Register(tools.NewWebFetchTool(50000))
// Register message tool

View File

@@ -157,13 +157,20 @@ type GatewayConfig struct {
Port int `json:"port" env:"PICOCLAW_GATEWAY_PORT"`
}
type WebSearchConfig struct {
APIKey string `json:"api_key" env:"PICOCLAW_TOOLS_WEB_SEARCH_API_KEY"`
MaxResults int `json:"max_results" env:"PICOCLAW_TOOLS_WEB_SEARCH_MAX_RESULTS"`
type BraveConfig struct {
Enabled bool `json:"enabled" env:"PICOCLAW_TOOLS_WEB_BRAVE_ENABLED"`
APIKey string `json:"api_key" env:"PICOCLAW_TOOLS_WEB_BRAVE_API_KEY"`
MaxResults int `json:"max_results" env:"PICOCLAW_TOOLS_WEB_BRAVE_MAX_RESULTS"`
}
type DuckDuckGoConfig struct {
Enabled bool `json:"enabled" env:"PICOCLAW_TOOLS_WEB_DUCKDUCKGO_ENABLED"`
MaxResults int `json:"max_results" env:"PICOCLAW_TOOLS_WEB_DUCKDUCKGO_MAX_RESULTS"`
}
type WebToolsConfig struct {
Search WebSearchConfig `json:"search"`
Brave BraveConfig `json:"brave"`
DuckDuckGo DuckDuckGoConfig `json:"duckduckgo"`
}
type ToolsConfig struct {
@@ -249,10 +256,15 @@ func DefaultConfig() *Config {
},
Tools: ToolsConfig{
Web: WebToolsConfig{
Search: WebSearchConfig{
Brave: BraveConfig{
Enabled: false,
APIKey: "",
MaxResults: 5,
},
DuckDuckGo: DuckDuckGoConfig{
Enabled: true,
MaxResults: 5,
},
},
},
}

View File

@@ -212,12 +212,17 @@ func ConvertConfig(data map[string]interface{}) (*config.Config, []string, error
if tools, ok := getMap(data, "tools"); ok {
if web, ok := getMap(tools, "web"); ok {
// Migrate old "search" config to "brave" if api_key is present
if search, ok := getMap(web, "search"); ok {
if v, ok := getString(search, "api_key"); ok {
cfg.Tools.Web.Search.APIKey = v
cfg.Tools.Web.Brave.APIKey = v
if v != "" {
cfg.Tools.Web.Brave.Enabled = true
}
}
if v, ok := getFloat(search, "max_results"); ok {
cfg.Tools.Web.Search.MaxResults = int(v)
cfg.Tools.Web.Brave.MaxResults = int(v)
cfg.Tools.Web.DuckDuckGo.MaxResults = int(v)
}
}
}
@@ -271,8 +276,8 @@ func MergeConfig(existing, incoming *config.Config) *config.Config {
existing.Channels.MaixCam = incoming.Channels.MaixCam
}
if existing.Tools.Web.Search.APIKey == "" {
existing.Tools.Web.Search = incoming.Tools.Web.Search
if existing.Tools.Web.Brave.APIKey == "" {
existing.Tools.Web.Brave = incoming.Tools.Web.Brave
}
return existing

View File

@@ -188,16 +188,31 @@ type WebSearchTool struct {
maxResults int
}
func NewWebSearchTool(apiKey string, maxResults int) *WebSearchTool {
if maxResults <= 0 || maxResults > 10 {
maxResults = 5
}
type WebSearchToolOptions struct {
BraveAPIKey string
BraveMaxResults int
BraveEnabled bool
DuckDuckGoMaxResults int
DuckDuckGoEnabled bool
}
func NewWebSearchTool(opts WebSearchToolOptions) *WebSearchTool {
var provider SearchProvider
if apiKey != "" {
provider = &BraveSearchProvider{apiKey: apiKey}
} else {
maxResults := 5
// Priority: Brave > DuckDuckGo
if opts.BraveEnabled && opts.BraveAPIKey != "" {
provider = &BraveSearchProvider{apiKey: opts.BraveAPIKey}
if opts.BraveMaxResults > 0 {
maxResults = opts.BraveMaxResults
}
} else if opts.DuckDuckGoEnabled {
provider = &DuckDuckGoSearchProvider{}
if opts.DuckDuckGoMaxResults > 0 {
maxResults = opts.DuckDuckGoMaxResults
}
} else {
return nil
}
return &WebSearchTool{