From 42d29373729dfa8cfa0d53b2203ad233ca59f4c8 Mon Sep 17 00:00:00 2001 From: "zenix.huang" Date: Wed, 18 Feb 2026 17:01:28 +0900 Subject: [PATCH] fix: use more elegant way to solve the issue. --- config/config.example.json | 4 +-- pkg/config/config.go | 44 +++++++++++++++------------- pkg/config/config_test.go | 16 +++++----- pkg/migrate/config.go | 12 +++++++- pkg/providers/codex_provider_test.go | 3 -- pkg/providers/http_provider.go | 8 +++-- 6 files changed, 50 insertions(+), 37 deletions(-) diff --git a/config/config.example.json b/config/config.example.json index 531ded27e..37c2bcd81 100644 --- a/config/config.example.json +++ b/config/config.example.json @@ -80,7 +80,7 @@ "openai": { "api_key": "", "api_base": "", - "codex_web_search": true + "web_search": true }, "openrouter": { "api_key": "sk-or-v1-xxx", @@ -145,4 +145,4 @@ "host": "0.0.0.0", "port": 18790 } -} \ No newline at end of file +} diff --git a/pkg/config/config.go b/pkg/config/config.go index cc744df95..92a4a5862 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -167,28 +167,32 @@ type DevicesConfig struct { } type ProvidersConfig struct { - Anthropic ProviderConfig `json:"anthropic"` - OpenAI ProviderConfig `json:"openai"` - OpenRouter ProviderConfig `json:"openrouter"` - Groq ProviderConfig `json:"groq"` - Zhipu ProviderConfig `json:"zhipu"` - VLLM ProviderConfig `json:"vllm"` - Gemini ProviderConfig `json:"gemini"` - Nvidia ProviderConfig `json:"nvidia"` - Ollama ProviderConfig `json:"ollama"` - Moonshot ProviderConfig `json:"moonshot"` - ShengSuanYun ProviderConfig `json:"shengsuanyun"` - DeepSeek ProviderConfig `json:"deepseek"` - GitHubCopilot ProviderConfig `json:"github_copilot"` + Anthropic ProviderConfig `json:"anthropic"` + OpenAI OpenAIProviderConfig `json:"openai"` + OpenRouter ProviderConfig `json:"openrouter"` + Groq ProviderConfig `json:"groq"` + Zhipu ProviderConfig `json:"zhipu"` + VLLM ProviderConfig `json:"vllm"` + Gemini ProviderConfig `json:"gemini"` + Nvidia ProviderConfig `json:"nvidia"` + Ollama ProviderConfig `json:"ollama"` + Moonshot ProviderConfig `json:"moonshot"` + ShengSuanYun ProviderConfig `json:"shengsuanyun"` + DeepSeek ProviderConfig `json:"deepseek"` + GitHubCopilot ProviderConfig `json:"github_copilot"` } type ProviderConfig struct { - APIKey string `json:"api_key" env:"PICOCLAW_PROVIDERS_{{.Name}}_API_KEY"` - APIBase string `json:"api_base" env:"PICOCLAW_PROVIDERS_{{.Name}}_API_BASE"` - Proxy string `json:"proxy,omitempty" env:"PICOCLAW_PROVIDERS_{{.Name}}_PROXY"` - AuthMethod string `json:"auth_method,omitempty" env:"PICOCLAW_PROVIDERS_{{.Name}}_AUTH_METHOD"` - ConnectMode string `json:"connect_mode,omitempty" env:"PICOCLAW_PROVIDERS_{{.Name}}_CONNECT_MODE"` //only for Github Copilot, `stdio` or `grpc` - CodexWebSearch bool `json:"codex_web_search,omitempty" env:"PICOCLAW_PROVIDERS_{{.Name}}_CODEX_WEB_SEARCH"` + APIKey string `json:"api_key" env:"PICOCLAW_PROVIDERS_{{.Name}}_API_KEY"` + APIBase string `json:"api_base" env:"PICOCLAW_PROVIDERS_{{.Name}}_API_BASE"` + Proxy string `json:"proxy,omitempty" env:"PICOCLAW_PROVIDERS_{{.Name}}_PROXY"` + AuthMethod string `json:"auth_method,omitempty" env:"PICOCLAW_PROVIDERS_{{.Name}}_AUTH_METHOD"` + ConnectMode string `json:"connect_mode,omitempty" env:"PICOCLAW_PROVIDERS_{{.Name}}_CONNECT_MODE"` //only for Github Copilot, `stdio` or `grpc` +} + +type OpenAIProviderConfig struct { + ProviderConfig + WebSearch bool `json:"web_search" env:"PICOCLAW_PROVIDERS_OPENAI_WEB_SEARCH"` } type GatewayConfig struct { @@ -309,7 +313,7 @@ func DefaultConfig() *Config { }, Providers: ProvidersConfig{ Anthropic: ProviderConfig{}, - OpenAI: ProviderConfig{CodexWebSearch: true}, + OpenAI: OpenAIProviderConfig{WebSearch: true}, OpenRouter: ProviderConfig{}, Groq: ProviderConfig{}, Zhipu: ProviderConfig{}, diff --git a/pkg/config/config_test.go b/pkg/config/config_test.go index 56a1eb849..a1f73f0b3 100644 --- a/pkg/config/config_test.go +++ b/pkg/config/config_test.go @@ -205,14 +205,14 @@ func TestConfig_Complete(t *testing.T) { } } -func TestDefaultConfig_OpenAICodexWebSearchEnabled(t *testing.T) { +func TestDefaultConfig_OpenAIWebSearchEnabled(t *testing.T) { cfg := DefaultConfig() - if !cfg.Providers.OpenAI.CodexWebSearch { - t.Fatal("DefaultConfig().Providers.OpenAI.CodexWebSearch should be true") + if !cfg.Providers.OpenAI.WebSearch { + t.Fatal("DefaultConfig().Providers.OpenAI.WebSearch should be true") } } -func TestLoadConfig_OpenAICodexWebSearchDefaultsTrueWhenUnset(t *testing.T) { +func TestLoadConfig_OpenAIWebSearchDefaultsTrueWhenUnset(t *testing.T) { dir := t.TempDir() configPath := filepath.Join(dir, "config.json") if err := os.WriteFile(configPath, []byte(`{"providers":{"openai":{"api_base":""}}}`), 0o600); err != nil { @@ -223,15 +223,15 @@ func TestLoadConfig_OpenAICodexWebSearchDefaultsTrueWhenUnset(t *testing.T) { if err != nil { t.Fatalf("LoadConfig() error: %v", err) } - if !cfg.Providers.OpenAI.CodexWebSearch { + if !cfg.Providers.OpenAI.WebSearch { t.Fatal("OpenAI codex web search should remain true when unset in config file") } } -func TestLoadConfig_OpenAICodexWebSearchCanBeDisabled(t *testing.T) { +func TestLoadConfig_OpenAIWebSearchCanBeDisabled(t *testing.T) { dir := t.TempDir() configPath := filepath.Join(dir, "config.json") - if err := os.WriteFile(configPath, []byte(`{"providers":{"openai":{"codex_web_search":false}}}`), 0o600); err != nil { + if err := os.WriteFile(configPath, []byte(`{"providers":{"openai":{"web_search":false}}}`), 0o600); err != nil { t.Fatalf("WriteFile() error: %v", err) } @@ -239,7 +239,7 @@ func TestLoadConfig_OpenAICodexWebSearchCanBeDisabled(t *testing.T) { if err != nil { t.Fatalf("LoadConfig() error: %v", err) } - if cfg.Providers.OpenAI.CodexWebSearch { + if cfg.Providers.OpenAI.WebSearch { t.Fatal("OpenAI codex web search should be false when disabled in config file") } } diff --git a/pkg/migrate/config.go b/pkg/migrate/config.go index 9c1e36359..57032e566 100644 --- a/pkg/migrate/config.go +++ b/pkg/migrate/config.go @@ -108,7 +108,10 @@ func ConvertConfig(data map[string]interface{}) (*config.Config, []string, error case "anthropic": cfg.Providers.Anthropic = pc case "openai": - cfg.Providers.OpenAI = pc + cfg.Providers.OpenAI = config.OpenAIProviderConfig{ + ProviderConfig: pc, + WebSearch: getBoolOrDefault(pMap, "web_search", true), + } case "openrouter": cfg.Providers.OpenRouter = pc case "groq": @@ -363,6 +366,13 @@ func getBool(data map[string]interface{}, key string) (bool, bool) { return b, ok } +func getBoolOrDefault(data map[string]interface{}, key string, defaultVal bool) bool { + if v, ok := getBool(data, key); ok { + return v + } + return defaultVal +} + func getStringSlice(data map[string]interface{}, key string) []string { v, ok := data[key] if !ok { diff --git a/pkg/providers/codex_provider_test.go b/pkg/providers/codex_provider_test.go index 3b983ab29..92e276165 100644 --- a/pkg/providers/codex_provider_test.go +++ b/pkg/providers/codex_provider_test.go @@ -32,9 +32,6 @@ func TestBuildCodexParams_BasicMessage(t *testing.T) { if params.MaxOutputTokens.Valid() { t.Fatalf("MaxOutputTokens should not be set for Codex backend") } - if params.MaxOutputTokens.Valid() { - t.Error("MaxOutputTokens should not be set for codex backend") - } } func TestBuildCodexParams_SystemAsInstructions(t *testing.T) { diff --git a/pkg/providers/http_provider.go b/pkg/providers/http_provider.go index ae27b85e8..946aa29d2 100644 --- a/pkg/providers/http_provider.go +++ b/pkg/providers/http_provider.go @@ -243,10 +243,12 @@ func CreateProvider(cfg *config.Config) (LLMProvider, error) { case "openai", "gpt": if cfg.Providers.OpenAI.APIKey != "" || cfg.Providers.OpenAI.AuthMethod != "" { if cfg.Providers.OpenAI.AuthMethod == "codex-cli" { - return NewCodexProviderWithTokenSource("", "", CreateCodexCliTokenSource()), nil + c := NewCodexProviderWithTokenSource("", "", CreateCodexCliTokenSource()) + c.enableWebSearch = cfg.Providers.OpenAI.WebSearch + return c, nil } if cfg.Providers.OpenAI.AuthMethod == "oauth" || cfg.Providers.OpenAI.AuthMethod == "token" { - return createCodexAuthProvider(cfg.Providers.OpenAI.CodexWebSearch) + return createCodexAuthProvider(cfg.Providers.OpenAI.WebSearch) } apiKey = cfg.Providers.OpenAI.APIKey apiBase = cfg.Providers.OpenAI.APIBase @@ -371,7 +373,7 @@ func CreateProvider(cfg *config.Config) (LLMProvider, error) { case (strings.Contains(lowerModel, "gpt") || strings.HasPrefix(model, "openai/")) && (cfg.Providers.OpenAI.APIKey != "" || cfg.Providers.OpenAI.AuthMethod != ""): if cfg.Providers.OpenAI.AuthMethod == "oauth" || cfg.Providers.OpenAI.AuthMethod == "token" { - return createCodexAuthProvider(cfg.Providers.OpenAI.CodexWebSearch) + return createCodexAuthProvider(cfg.Providers.OpenAI.WebSearch) } apiKey = cfg.Providers.OpenAI.APIKey apiBase = cfg.Providers.OpenAI.APIBase