mirror of
https://github.com/sipeed/picoclaw.git
synced 2026-06-12 18:08:54 +00:00
feat(providers): add gemini web search provider (#2763)
* add gemini web search provider * fix(web): prefer free providers before Gemini in auto mode * fix(web): expose gemini api key and model settings * fix(web): prefer configured providers before Gemini in auto mode * fix(web): satisfy gemini lint checks * fix(web): address gemini provider review feedback * test(web): align auto-provider expectations * fix(web): let gemini ignore search range
This commit is contained in:
committed by
GitHub
parent
eb0653074b
commit
794eb04f32
@@ -49,6 +49,7 @@ type webSearchProviderConfig struct {
|
||||
BaseURL string `json:"base_url,omitempty"`
|
||||
APIKey string `json:"api_key,omitempty"`
|
||||
APIKeys []string `json:"api_keys,omitempty"`
|
||||
Model string `json:"model,omitempty"`
|
||||
APIKeySet bool `json:"api_key_set,omitempty"`
|
||||
}
|
||||
|
||||
@@ -446,6 +447,14 @@ func (h *Handler) handleUpdateWebSearchConfig(w http.ResponseWriter, r *http.Req
|
||||
cfg.Tools.Web.DuckDuckGo.Enabled = settings.Enabled
|
||||
cfg.Tools.Web.DuckDuckGo.MaxResults = settings.MaxResults
|
||||
}
|
||||
if settings, ok := req.Settings["gemini"]; ok {
|
||||
cfg.Tools.Web.Gemini.Enabled = settings.Enabled
|
||||
cfg.Tools.Web.Gemini.MaxResults = settings.MaxResults
|
||||
cfg.Tools.Web.Gemini.Model = strings.TrimSpace(settings.Model)
|
||||
if key := strings.TrimSpace(settings.APIKey); key != "" {
|
||||
cfg.Tools.Web.Gemini.APIKey = *config.NewSecureString(key)
|
||||
}
|
||||
}
|
||||
if settings, ok := req.Settings["brave"]; ok {
|
||||
cfg.Tools.Web.Brave.Enabled = settings.Enabled
|
||||
cfg.Tools.Web.Brave.MaxResults = settings.MaxResults
|
||||
@@ -505,7 +514,7 @@ func normalizeWebSearchProvider(provider string) string {
|
||||
switch strings.ToLower(strings.TrimSpace(provider)) {
|
||||
case "", "auto":
|
||||
return "auto"
|
||||
case "sogou", "brave", "tavily", "duckduckgo", "perplexity", "searxng", "glm_search", "baidu_search":
|
||||
case "sogou", "brave", "tavily", "duckduckgo", "gemini", "perplexity", "searxng", "glm_search", "baidu_search":
|
||||
return strings.ToLower(strings.TrimSpace(provider))
|
||||
default:
|
||||
return ""
|
||||
@@ -549,6 +558,12 @@ func buildWebSearchConfigResponse(cfg *config.Config) webSearchConfigResponse {
|
||||
Enabled: cfg.Tools.Web.DuckDuckGo.Enabled,
|
||||
MaxResults: cfg.Tools.Web.DuckDuckGo.MaxResults,
|
||||
},
|
||||
"gemini": {
|
||||
Enabled: cfg.Tools.Web.Gemini.Enabled,
|
||||
MaxResults: cfg.Tools.Web.Gemini.MaxResults,
|
||||
Model: cfg.Tools.Web.Gemini.Model,
|
||||
APIKeySet: cfg.Tools.Web.Gemini.APIKey.String() != "",
|
||||
},
|
||||
"brave": {
|
||||
Enabled: cfg.Tools.Web.Brave.Enabled,
|
||||
MaxResults: cfg.Tools.Web.Brave.MaxResults,
|
||||
@@ -604,6 +619,13 @@ func buildWebSearchConfigResponse(cfg *config.Config) webSearchConfigResponse {
|
||||
Configured: picotools.WebSearchProviderReady(opts, "duckduckgo"),
|
||||
Current: current == "duckduckgo",
|
||||
},
|
||||
{
|
||||
ID: "gemini",
|
||||
Label: "Gemini (Google Search)",
|
||||
Configured: picotools.WebSearchProviderReady(opts, "gemini"),
|
||||
Current: current == "gemini",
|
||||
RequiresAuth: true,
|
||||
},
|
||||
{
|
||||
ID: "brave",
|
||||
Label: "Brave Search",
|
||||
|
||||
@@ -540,7 +540,7 @@ func TestHandleUpdateWebSearchConfig_PreservesAndReplacesMultiKeys(t *testing.T)
|
||||
}
|
||||
}
|
||||
|
||||
func TestResolveCurrentWebSearchProvider_PrefersConfiguredProvidersBeforeSogou(t *testing.T) {
|
||||
func TestResolveCurrentWebSearchProvider_PrefersConfiguredProvidersInAutoMode(t *testing.T) {
|
||||
cfg := config.DefaultConfig()
|
||||
cfg.Tools.Web.Provider = "auto"
|
||||
cfg.Tools.Web.Sogou.Enabled = true
|
||||
|
||||
@@ -30,6 +30,7 @@ export interface WebSearchProviderConfig {
|
||||
max_results: number
|
||||
base_url?: string
|
||||
api_key?: string
|
||||
model?: string
|
||||
api_key_set?: boolean
|
||||
}
|
||||
|
||||
|
||||
@@ -30,10 +30,13 @@ const apiKeyProviders = new Set([
|
||||
"brave",
|
||||
"tavily",
|
||||
"perplexity",
|
||||
"gemini",
|
||||
"glm_search",
|
||||
"baidu_search",
|
||||
])
|
||||
|
||||
const modelProviders = new Set(["gemini"])
|
||||
|
||||
export function WebSearchProviderSettings({
|
||||
providerLabelMap,
|
||||
settings,
|
||||
@@ -226,6 +229,27 @@ function ProviderCard({
|
||||
/>
|
||||
</ProviderField>
|
||||
)}
|
||||
|
||||
{modelProviders.has(providerId) && (
|
||||
<ProviderField
|
||||
label={t("pages.agent.tools.web_search.model", "Model")}
|
||||
>
|
||||
<Input
|
||||
value={settings.model ?? ""}
|
||||
onChange={(event) =>
|
||||
updateSettings((current) => ({
|
||||
...current,
|
||||
model: event.target.value,
|
||||
}))
|
||||
}
|
||||
placeholder={t(
|
||||
"pages.agent.tools.web_search.model_placeholder",
|
||||
"Optional model override",
|
||||
)}
|
||||
className="bg-muted/40 hover:bg-muted/60 focus:bg-background focus:ring-primary/20 h-10 rounded-xl border-transparent shadow-none transition-colors"
|
||||
/>
|
||||
</ProviderField>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
Reference in New Issue
Block a user