feat: add support for DuckDuckGo and refactor Brave search configuration support the control with config.js
This commit is contained in:
24
README.md
24
README.md
@@ -194,9 +194,14 @@ picoclaw onboard
|
|||||||
},
|
},
|
||||||
"tools": {
|
"tools": {
|
||||||
"web": {
|
"web": {
|
||||||
"search": {
|
"brave": {
|
||||||
|
"enabled": false,
|
||||||
"api_key": "YOUR_BRAVE_API_KEY",
|
"api_key": "YOUR_BRAVE_API_KEY",
|
||||||
"max_results": 5
|
"max_results": 5
|
||||||
|
},
|
||||||
|
"duckduckgo": {
|
||||||
|
"enabled": true,
|
||||||
|
"max_results": 5
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -507,8 +512,14 @@ picoclaw agent -m "Hello"
|
|||||||
},
|
},
|
||||||
"tools": {
|
"tools": {
|
||||||
"web": {
|
"web": {
|
||||||
"search": {
|
"brave": {
|
||||||
"api_key": "BSA..."
|
"enabled": false,
|
||||||
|
"api_key": "BSA...",
|
||||||
|
"max_results": 5
|
||||||
|
},
|
||||||
|
"duckduckgo": {
|
||||||
|
"enabled": true,
|
||||||
|
"max_results": 5
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -564,9 +575,14 @@ Add the key to `~/.picoclaw/config.json` if using Brave:
|
|||||||
{
|
{
|
||||||
"tools": {
|
"tools": {
|
||||||
"web": {
|
"web": {
|
||||||
"search": {
|
"brave": {
|
||||||
|
"enabled": false,
|
||||||
"api_key": "YOUR_BRAVE_API_KEY",
|
"api_key": "YOUR_BRAVE_API_KEY",
|
||||||
"max_results": 5
|
"max_results": 5
|
||||||
|
},
|
||||||
|
"duckduckgo": {
|
||||||
|
"enabled": true,
|
||||||
|
"max_results": 5
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -63,8 +63,15 @@ func NewAgentLoop(cfg *config.Config, msgBus *bus.MessageBus, provider providers
|
|||||||
toolsRegistry.Register(tools.NewListDirTool(workspace, restrict))
|
toolsRegistry.Register(tools.NewListDirTool(workspace, restrict))
|
||||||
toolsRegistry.Register(tools.NewExecTool(workspace, restrict))
|
toolsRegistry.Register(tools.NewExecTool(workspace, restrict))
|
||||||
|
|
||||||
braveAPIKey := cfg.Tools.Web.Search.APIKey
|
if searchTool := tools.NewWebSearchTool(tools.WebSearchToolOptions{
|
||||||
toolsRegistry.Register(tools.NewWebSearchTool(braveAPIKey, cfg.Tools.Web.Search.MaxResults))
|
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))
|
toolsRegistry.Register(tools.NewWebFetchTool(50000))
|
||||||
|
|
||||||
// Register message tool
|
// Register message tool
|
||||||
|
|||||||
@@ -157,13 +157,20 @@ type GatewayConfig struct {
|
|||||||
Port int `json:"port" env:"PICOCLAW_GATEWAY_PORT"`
|
Port int `json:"port" env:"PICOCLAW_GATEWAY_PORT"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type WebSearchConfig struct {
|
type BraveConfig struct {
|
||||||
APIKey string `json:"api_key" env:"PICOCLAW_TOOLS_WEB_SEARCH_API_KEY"`
|
Enabled bool `json:"enabled" env:"PICOCLAW_TOOLS_WEB_BRAVE_ENABLED"`
|
||||||
MaxResults int `json:"max_results" env:"PICOCLAW_TOOLS_WEB_SEARCH_MAX_RESULTS"`
|
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 {
|
type WebToolsConfig struct {
|
||||||
Search WebSearchConfig `json:"search"`
|
Brave BraveConfig `json:"brave"`
|
||||||
|
DuckDuckGo DuckDuckGoConfig `json:"duckduckgo"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type ToolsConfig struct {
|
type ToolsConfig struct {
|
||||||
@@ -249,10 +256,15 @@ func DefaultConfig() *Config {
|
|||||||
},
|
},
|
||||||
Tools: ToolsConfig{
|
Tools: ToolsConfig{
|
||||||
Web: WebToolsConfig{
|
Web: WebToolsConfig{
|
||||||
Search: WebSearchConfig{
|
Brave: BraveConfig{
|
||||||
|
Enabled: false,
|
||||||
APIKey: "",
|
APIKey: "",
|
||||||
MaxResults: 5,
|
MaxResults: 5,
|
||||||
},
|
},
|
||||||
|
DuckDuckGo: DuckDuckGoConfig{
|
||||||
|
Enabled: true,
|
||||||
|
MaxResults: 5,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -212,12 +212,17 @@ func ConvertConfig(data map[string]interface{}) (*config.Config, []string, error
|
|||||||
|
|
||||||
if tools, ok := getMap(data, "tools"); ok {
|
if tools, ok := getMap(data, "tools"); ok {
|
||||||
if web, ok := getMap(tools, "web"); 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 search, ok := getMap(web, "search"); ok {
|
||||||
if v, ok := getString(search, "api_key"); 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 {
|
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
|
existing.Channels.MaixCam = incoming.Channels.MaixCam
|
||||||
}
|
}
|
||||||
|
|
||||||
if existing.Tools.Web.Search.APIKey == "" {
|
if existing.Tools.Web.Brave.APIKey == "" {
|
||||||
existing.Tools.Web.Search = incoming.Tools.Web.Search
|
existing.Tools.Web.Brave = incoming.Tools.Web.Brave
|
||||||
}
|
}
|
||||||
|
|
||||||
return existing
|
return existing
|
||||||
|
|||||||
@@ -188,16 +188,31 @@ type WebSearchTool struct {
|
|||||||
maxResults int
|
maxResults int
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewWebSearchTool(apiKey string, maxResults int) *WebSearchTool {
|
type WebSearchToolOptions struct {
|
||||||
if maxResults <= 0 || maxResults > 10 {
|
BraveAPIKey string
|
||||||
maxResults = 5
|
BraveMaxResults int
|
||||||
|
BraveEnabled bool
|
||||||
|
DuckDuckGoMaxResults int
|
||||||
|
DuckDuckGoEnabled bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewWebSearchTool(opts WebSearchToolOptions) *WebSearchTool {
|
||||||
var provider SearchProvider
|
var provider SearchProvider
|
||||||
if apiKey != "" {
|
maxResults := 5
|
||||||
provider = &BraveSearchProvider{apiKey: apiKey}
|
|
||||||
} else {
|
// 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{}
|
provider = &DuckDuckGoSearchProvider{}
|
||||||
|
if opts.DuckDuckGoMaxResults > 0 {
|
||||||
|
maxResults = opts.DuckDuckGoMaxResults
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return &WebSearchTool{
|
return &WebSearchTool{
|
||||||
|
|||||||
Reference in New Issue
Block a user