feat(providers): support custom request headers in HTTP providers
This commit is contained in:
parent
2f4f45080b
commit
41eaf48516
4 changed files with 36 additions and 13 deletions
|
|
@ -464,6 +464,7 @@ type ModelConfig struct {
|
||||||
APIBase string `json:"api_base,omitempty"` // API endpoint URL
|
APIBase string `json:"api_base,omitempty"` // API endpoint URL
|
||||||
APIKey string `json:"api_key"` // API authentication key
|
APIKey string `json:"api_key"` // API authentication key
|
||||||
Proxy string `json:"proxy,omitempty"` // HTTP proxy URL
|
Proxy string `json:"proxy,omitempty"` // HTTP proxy URL
|
||||||
|
Headers map[string]string `json:"headers,omitempty"` // Custom HTTP headers
|
||||||
|
|
||||||
// Special providers (CLI-based, OAuth, etc.)
|
// Special providers (CLI-based, OAuth, etc.)
|
||||||
AuthMethod string `json:"auth_method,omitempty"` // Authentication method: oauth, token
|
AuthMethod string `json:"auth_method,omitempty"` // Authentication method: oauth, token
|
||||||
|
|
|
||||||
|
|
@ -84,12 +84,13 @@ func CreateProviderFromConfig(cfg *config.ModelConfig) (LLMProvider, string, err
|
||||||
if apiBase == "" {
|
if apiBase == "" {
|
||||||
apiBase = getDefaultAPIBase(protocol)
|
apiBase = getDefaultAPIBase(protocol)
|
||||||
}
|
}
|
||||||
return NewHTTPProviderWithMaxTokensFieldAndRequestTimeout(
|
return NewHTTPProviderWithOptions(
|
||||||
cfg.APIKey,
|
cfg.APIKey,
|
||||||
apiBase,
|
apiBase,
|
||||||
cfg.Proxy,
|
cfg.Proxy,
|
||||||
cfg.MaxTokensField,
|
cfg.MaxTokensField,
|
||||||
cfg.RequestTimeout,
|
cfg.RequestTimeout,
|
||||||
|
cfg.Headers,
|
||||||
), modelID, nil
|
), modelID, nil
|
||||||
|
|
||||||
case "openrouter", "groq", "zhipu", "gemini", "nvidia",
|
case "openrouter", "groq", "zhipu", "gemini", "nvidia",
|
||||||
|
|
@ -103,12 +104,13 @@ func CreateProviderFromConfig(cfg *config.ModelConfig) (LLMProvider, string, err
|
||||||
if apiBase == "" {
|
if apiBase == "" {
|
||||||
apiBase = getDefaultAPIBase(protocol)
|
apiBase = getDefaultAPIBase(protocol)
|
||||||
}
|
}
|
||||||
return NewHTTPProviderWithMaxTokensFieldAndRequestTimeout(
|
return NewHTTPProviderWithOptions(
|
||||||
cfg.APIKey,
|
cfg.APIKey,
|
||||||
apiBase,
|
apiBase,
|
||||||
cfg.Proxy,
|
cfg.Proxy,
|
||||||
cfg.MaxTokensField,
|
cfg.MaxTokensField,
|
||||||
cfg.RequestTimeout,
|
cfg.RequestTimeout,
|
||||||
|
cfg.Headers,
|
||||||
), modelID, nil
|
), modelID, nil
|
||||||
|
|
||||||
case "anthropic":
|
case "anthropic":
|
||||||
|
|
@ -128,12 +130,13 @@ func CreateProviderFromConfig(cfg *config.ModelConfig) (LLMProvider, string, err
|
||||||
if cfg.APIKey == "" {
|
if cfg.APIKey == "" {
|
||||||
return nil, "", fmt.Errorf("api_key is required for anthropic protocol (model: %s)", cfg.Model)
|
return nil, "", fmt.Errorf("api_key is required for anthropic protocol (model: %s)", cfg.Model)
|
||||||
}
|
}
|
||||||
return NewHTTPProviderWithMaxTokensFieldAndRequestTimeout(
|
return NewHTTPProviderWithOptions(
|
||||||
cfg.APIKey,
|
cfg.APIKey,
|
||||||
apiBase,
|
apiBase,
|
||||||
cfg.Proxy,
|
cfg.Proxy,
|
||||||
cfg.MaxTokensField,
|
cfg.MaxTokensField,
|
||||||
cfg.RequestTimeout,
|
cfg.RequestTimeout,
|
||||||
|
cfg.Headers,
|
||||||
), modelID, nil
|
), modelID, nil
|
||||||
|
|
||||||
case "antigravity":
|
case "antigravity":
|
||||||
|
|
|
||||||
|
|
@ -31,14 +31,23 @@ func NewHTTPProviderWithMaxTokensFieldAndRequestTimeout(
|
||||||
apiKey, apiBase, proxy, maxTokensField string,
|
apiKey, apiBase, proxy, maxTokensField string,
|
||||||
requestTimeoutSeconds int,
|
requestTimeoutSeconds int,
|
||||||
) *HTTPProvider {
|
) *HTTPProvider {
|
||||||
return &HTTPProvider{
|
return NewHTTPProviderWithOptions(apiKey, apiBase, proxy, maxTokensField, requestTimeoutSeconds, nil)
|
||||||
delegate: openai_compat.NewProvider(
|
}
|
||||||
apiKey,
|
|
||||||
apiBase,
|
func NewHTTPProviderWithOptions(
|
||||||
proxy,
|
apiKey, apiBase, proxy, maxTokensField string,
|
||||||
|
requestTimeoutSeconds int,
|
||||||
|
customHeaders map[string]string,
|
||||||
|
) *HTTPProvider {
|
||||||
|
opts := []openai_compat.Option{
|
||||||
openai_compat.WithMaxTokensField(maxTokensField),
|
openai_compat.WithMaxTokensField(maxTokensField),
|
||||||
openai_compat.WithRequestTimeout(time.Duration(requestTimeoutSeconds) * time.Second),
|
openai_compat.WithRequestTimeout(time.Duration(requestTimeoutSeconds) * time.Second),
|
||||||
),
|
}
|
||||||
|
if customHeaders != nil {
|
||||||
|
opts = append(opts, openai_compat.WithCustomHeaders(customHeaders))
|
||||||
|
}
|
||||||
|
return &HTTPProvider{
|
||||||
|
delegate: openai_compat.NewProvider(apiKey, apiBase, proxy, opts...),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,7 @@ type Provider struct {
|
||||||
apiKey string
|
apiKey string
|
||||||
apiBase string
|
apiBase string
|
||||||
maxTokensField string // Field name for max tokens (e.g., "max_completion_tokens" for o1/glm models)
|
maxTokensField string // Field name for max tokens (e.g., "max_completion_tokens" for o1/glm models)
|
||||||
|
customHeaders map[string]string
|
||||||
httpClient *http.Client
|
httpClient *http.Client
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -53,6 +54,12 @@ func WithRequestTimeout(timeout time.Duration) Option {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func WithCustomHeaders(headers map[string]string) Option {
|
||||||
|
return func(p *Provider) {
|
||||||
|
p.customHeaders = headers
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func NewProvider(apiKey, apiBase, proxy string, opts ...Option) *Provider {
|
func NewProvider(apiKey, apiBase, proxy string, opts ...Option) *Provider {
|
||||||
client := &http.Client{
|
client := &http.Client{
|
||||||
Timeout: defaultRequestTimeout,
|
Timeout: defaultRequestTimeout,
|
||||||
|
|
@ -176,6 +183,9 @@ func (p *Provider) Chat(
|
||||||
if p.apiKey != "" {
|
if p.apiKey != "" {
|
||||||
req.Header.Set("Authorization", "Bearer "+p.apiKey)
|
req.Header.Set("Authorization", "Bearer "+p.apiKey)
|
||||||
}
|
}
|
||||||
|
for key, value := range p.customHeaders {
|
||||||
|
req.Header.Set(key, value)
|
||||||
|
}
|
||||||
|
|
||||||
resp, err := p.httpClient.Do(req)
|
resp, err := p.httpClient.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue