From 38df3a7ae542397ab6e79f2f62d7967ec06cced1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9B=BE=E6=96=87=E9=94=8B0668000834?= Date: Thu, 12 Mar 2026 20:58:07 +0800 Subject: [PATCH] fix(provider): add insecure_skip_verify option for HTTP providers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add insecure_skip_verify configuration option to ModelConfig to allow skipping TLS certificate verification for development/testing environments. This fixes SSL certificate verification issues when using volcengine and other providers in environments with missing or outdated CA certificates (e.g., Android Termux). Changes: - Add InsecureSkipVerify field to ModelConfig in config.go - Add WithInsecureSkipVerify option function in openai_compat/provider.go - Add NewHTTPProviderWithOptions function in http_provider.go - Update factory_provider.go to pass insecure_skip_verify to all HTTP providers Usage example in config.json: { "model_list": [{ "model_name": "doubao", "model": "volcengine/doubao-pro", "api_key": "your-api-key", "insecure_skip_verify": true }] } 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- pkg/config/config.go | 3 +++ pkg/providers/factory_provider.go | 9 ++++++--- pkg/providers/http_provider.go | 16 ++++++++++++++++ pkg/providers/openai_compat/provider.go | 19 +++++++++++++++++++ 4 files changed, 44 insertions(+), 3 deletions(-) diff --git a/pkg/config/config.go b/pkg/config/config.go index e3520faaf..6c18145e4 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -563,6 +563,9 @@ type ModelConfig struct { MaxTokensField string `json:"max_tokens_field,omitempty"` // Field name for max tokens (e.g., "max_completion_tokens") RequestTimeout int `json:"request_timeout,omitempty"` ThinkingLevel string `json:"thinking_level,omitempty"` // Extended thinking: off|low|medium|high|xhigh|adaptive + + // TLS configuration + InsecureSkipVerify bool `json:"insecure_skip_verify,omitempty"` // Skip TLS certificate verification (for development/testing only) } // Validate checks if the ModelConfig has all required fields. diff --git a/pkg/providers/factory_provider.go b/pkg/providers/factory_provider.go index a798154cb..7d02827af 100644 --- a/pkg/providers/factory_provider.go +++ b/pkg/providers/factory_provider.go @@ -84,12 +84,13 @@ func CreateProviderFromConfig(cfg *config.ModelConfig) (LLMProvider, string, err if apiBase == "" { apiBase = getDefaultAPIBase(protocol) } - return NewHTTPProviderWithMaxTokensFieldAndRequestTimeout( + return NewHTTPProviderWithOptions( cfg.APIKey, apiBase, cfg.Proxy, cfg.MaxTokensField, cfg.RequestTimeout, + cfg.InsecureSkipVerify, ), modelID, nil case "litellm", "openrouter", "groq", "zhipu", "gemini", "nvidia", @@ -104,12 +105,13 @@ func CreateProviderFromConfig(cfg *config.ModelConfig) (LLMProvider, string, err if apiBase == "" { apiBase = getDefaultAPIBase(protocol) } - return NewHTTPProviderWithMaxTokensFieldAndRequestTimeout( + return NewHTTPProviderWithOptions( cfg.APIKey, apiBase, cfg.Proxy, cfg.MaxTokensField, cfg.RequestTimeout, + cfg.InsecureSkipVerify, ), modelID, nil case "anthropic": @@ -129,12 +131,13 @@ func CreateProviderFromConfig(cfg *config.ModelConfig) (LLMProvider, string, err if cfg.APIKey == "" { return nil, "", fmt.Errorf("api_key is required for anthropic protocol (model: %s)", cfg.Model) } - return NewHTTPProviderWithMaxTokensFieldAndRequestTimeout( + return NewHTTPProviderWithOptions( cfg.APIKey, apiBase, cfg.Proxy, cfg.MaxTokensField, cfg.RequestTimeout, + cfg.InsecureSkipVerify, ), modelID, nil case "antigravity": diff --git a/pkg/providers/http_provider.go b/pkg/providers/http_provider.go index 5c328f418..ffe2eca8a 100644 --- a/pkg/providers/http_provider.go +++ b/pkg/providers/http_provider.go @@ -30,6 +30,21 @@ func NewHTTPProviderWithMaxTokensField(apiKey, apiBase, proxy, maxTokensField st func NewHTTPProviderWithMaxTokensFieldAndRequestTimeout( apiKey, apiBase, proxy, maxTokensField string, requestTimeoutSeconds int, +) *HTTPProvider { + return NewHTTPProviderWithOptions( + apiKey, + apiBase, + proxy, + maxTokensField, + requestTimeoutSeconds, + false, + ) +} + +func NewHTTPProviderWithOptions( + apiKey, apiBase, proxy, maxTokensField string, + requestTimeoutSeconds int, + insecureSkipVerify bool, ) *HTTPProvider { return &HTTPProvider{ delegate: openai_compat.NewProvider( @@ -38,6 +53,7 @@ func NewHTTPProviderWithMaxTokensFieldAndRequestTimeout( proxy, openai_compat.WithMaxTokensField(maxTokensField), openai_compat.WithRequestTimeout(time.Duration(requestTimeoutSeconds)*time.Second), + openai_compat.WithInsecureSkipVerify(insecureSkipVerify), ), } } diff --git a/pkg/providers/openai_compat/provider.go b/pkg/providers/openai_compat/provider.go index 0e8db7409..8751b7092 100644 --- a/pkg/providers/openai_compat/provider.go +++ b/pkg/providers/openai_compat/provider.go @@ -4,6 +4,7 @@ import ( "bufio" "bytes" "context" + "crypto/tls" "encoding/json" "fmt" "io" @@ -54,6 +55,24 @@ func WithRequestTimeout(timeout time.Duration) Option { } } +func WithInsecureSkipVerify(skip bool) Option { + return func(p *Provider) { + if skip { + transport := p.httpClient.Transport + if transport == nil { + transport = &http.Transport{} + } + if tr, ok := transport.(*http.Transport); ok { + if tr.TLSClientConfig == nil { + tr.TLSClientConfig = &tls.Config{} + } + tr.TLSClientConfig.InsecureSkipVerify = true + p.httpClient.Transport = tr + } + } + } +} + func NewProvider(apiKey, apiBase, proxy string, opts ...Option) *Provider { client := &http.Client{ Timeout: defaultRequestTimeout,