Skip to content

Commit

Permalink
feat: add llm api proxy parameters (#782)
Browse files Browse the repository at this point in the history
## What type of PR is this?
/kind feature

## What this PR does / why we need it:
add llm api proxy parameters

## Which issue(s) this PR fixes:

Fixes #736
  • Loading branch information
jinjiaKarl authored Feb 8, 2025
1 parent c1a6f6e commit b9b540b
Show file tree
Hide file tree
Showing 6 changed files with 108 additions and 20 deletions.
13 changes: 13 additions & 0 deletions cmd/karpor/app/options/ai.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ type AIOptions struct {
AIModel string
AITemperature float32
AITopP float32
// proxy options
AIProxyEnabled bool
AIHTTPProxy string
AIHTTPSProxy string
AINoProxy string
}

const (
Expand All @@ -51,6 +56,10 @@ func (o *AIOptions) ApplyTo(config *registry.ExtraConfig) error {
config.AIModel = o.AIModel
config.AITemperature = o.AITemperature
config.AITopP = o.AITopP
config.AIProxyEnabled = o.AIProxyEnabled
config.AIHTTPProxy = o.AIHTTPProxy
config.AIHTTPSProxy = o.AIHTTPSProxy
config.AINoProxy = o.AINoProxy
return nil
}

Expand All @@ -66,4 +75,8 @@ func (o *AIOptions) AddFlags(fs *pflag.FlagSet) {
fs.StringVar(&o.AIModel, "ai-model", defaultModel, "The ai model")
fs.Float32Var(&o.AITemperature, "ai-temperature", defaultTemperature, "The ai temperature")
fs.Float32Var(&o.AITopP, "ai-top-p", defaultTopP, "The ai top-p")
fs.BoolVar(&o.AIProxyEnabled, "ai-proxy-enabled", false, "The ai proxy enable")
fs.StringVar(&o.AIHTTPProxy, "ai-http-proxy", "", "The ai http proxy")
fs.StringVar(&o.AIHTTPSProxy, "ai-https-proxy", "", "The ai https proxy")
fs.StringVar(&o.AINoProxy, "ai-no-proxy", "", "The ai no-proxy")
}
4 changes: 4 additions & 0 deletions pkg/infra/ai/azureopenai.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ func (c *AzureAIClient) Configure(cfg AIConfig) error {

defaultConfig := openai.DefaultAzureConfig(cfg.AuthToken, cfg.BaseURL)

if cfg.ProxyEnabled {
defaultConfig.HTTPClient.Transport = GetProxyHTTPClient(cfg)
}

client := openai.NewClientWithConfig(defaultConfig)
if client == nil {
return errors.New("error creating Azure OpenAI client")
Expand Down
12 changes: 10 additions & 2 deletions pkg/infra/ai/huggingface.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ package ai

import (
"context"
"net/http"

"github.com/hupe1980/go-huggingface"
)
Expand All @@ -27,9 +28,16 @@ type HuggingfaceClient struct {
}

func (c *HuggingfaceClient) Configure(cfg AIConfig) error {
client := huggingface.NewInferenceClient(cfg.AuthToken)
if cfg.ProxyEnabled {
c.client = huggingface.NewInferenceClient(cfg.AuthToken, func(o *huggingface.InferenceClientOptions) {
o.HTTPClient = &http.Client{
Transport: GetProxyHTTPClient(cfg),
}
})
} else {
c.client = huggingface.NewInferenceClient(cfg.AuthToken)
}

c.client = client
c.model = cfg.Model
c.temperature = cfg.Temperature
return nil
Expand Down
4 changes: 4 additions & 0 deletions pkg/infra/ai/openai.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ func (c *OpenAIClient) Configure(cfg AIConfig) error {
defaultConfig.BaseURL = cfg.BaseURL
}

if cfg.ProxyEnabled {
defaultConfig.HTTPClient.Transport = GetProxyHTTPClient(cfg)
}

client := openai.NewClientWithConfig(defaultConfig)
if client == nil {
return errors.New("error creating OpenAI client")
Expand Down
79 changes: 67 additions & 12 deletions pkg/infra/ai/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,12 @@ package ai

import (
"context"
"net/http"
"net/url"
"strings"

"github.com/KusionStack/karpor/pkg/kubernetes/registry"
"k8s.io/klog/v2"
)

const (
Expand Down Expand Up @@ -52,22 +56,30 @@ type AIProvider interface {

// AIConfig represents the configuration settings for an AI client.
type AIConfig struct {
Name string
AuthToken string
BaseURL string
Model string
Temperature float32
TopP float32
Name string
AuthToken string
BaseURL string
Model string
Temperature float32
TopP float32
ProxyEnabled bool
HTTPProxy string
HTTPSProxy string
NoProxy string
}

func ConvertToAIConfig(c registry.ExtraConfig) AIConfig {
return AIConfig{
Name: c.AIBackend,
AuthToken: c.AIAuthToken,
BaseURL: c.AIBaseURL,
Model: c.AIModel,
Temperature: c.AITemperature,
TopP: c.AITopP,
Name: c.AIBackend,
AuthToken: c.AIAuthToken,
BaseURL: c.AIBaseURL,
Model: c.AIModel,
Temperature: c.AITemperature,
TopP: c.AITopP,
ProxyEnabled: c.AIProxyEnabled,
HTTPProxy: c.AIHTTPProxy,
HTTPSProxy: c.AIHTTPSProxy,
NoProxy: c.AINoProxy,
}
}

Expand All @@ -79,3 +91,46 @@ func NewClient(name string) AIProvider {
// default client
return &OpenAIClient{}
}

// GetProxyHTTPClient returns a new http.Transport with proxy configuration
func GetProxyHTTPClient(cfg AIConfig) *http.Transport {
noProxyList := strings.Split(cfg.NoProxy, ",")

return &http.Transport{
Proxy: func(req *http.Request) (*url.URL, error) {
host := req.URL.Host
// Check if host matches NoProxy list
for _, np := range noProxyList {
if np = strings.TrimSpace(np); np != "" {
// exact match
if host == np {
klog.Infof("Skip proxy for %s: exact match in no_proxy list", host)
return nil, nil
}
// Domain suffix match with dot to prevent false positives
// e.g. pattern "le.com", it would incorrectly match host "example.com".
if !strings.HasPrefix(np, ".") {
np = "." + np
}
if strings.HasSuffix(host, np) {
klog.Infof("Skip proxy for %s: suffix match with %s in no_proxy list", host, np)
return nil, nil
}
}
}

var proxyURL string
if req.URL.Scheme == "https" && cfg.HTTPSProxy != "" {
proxyURL = cfg.HTTPSProxy
} else if req.URL.Scheme == "http" && cfg.HTTPProxy != "" {
proxyURL = cfg.HTTPProxy
}

if proxyURL != "" {
klog.Infof("Using proxy %s for %s", proxyURL, req.URL)
return url.Parse(proxyURL)
}
return nil, nil
},
}
}
16 changes: 10 additions & 6 deletions pkg/kubernetes/registry/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,14 @@ type ExtraConfig struct {
ExtendExpiration bool

// AI configs
AIBackend string
AIAuthToken string
AIBaseURL string
AIModel string
AITemperature float32
AITopP float32
AIBackend string
AIAuthToken string
AIBaseURL string
AIModel string
AITemperature float32
AITopP float32
AIProxyEnabled bool
AIHTTPProxy string
AIHTTPSProxy string
AINoProxy string
}

0 comments on commit b9b540b

Please sign in to comment.