Skip to content

Commit b9d7f8a

Browse files
authored
feat: add proxy and SOCKS5 support to HTTP Anthropic client (#213)
- Add support for proxy URL, SOCKS URL, and skip verify options in the Anthropic client configuration - Introduce `DefaultHeaderTransport` to add custom headers to HTTP requests - Add new HTTP transport configuration for handling proxy and SOCKS URLs - Update the Anthropic client initialization to use the new HTTP client with custom transport - Add `WithProxyURL`, `WithSocksURL`, and `WithSkipVerify` options for configuring the Anthropic client Signed-off-by: appleboy <[email protected]>
1 parent bfab13b commit b9d7f8a

File tree

3 files changed

+79
-1
lines changed

3 files changed

+79
-1
lines changed

cmd/provider.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,9 @@ func NewAnthropic(ctx context.Context) (*anthropic.Client, error) {
6262
anthropic.WithMaxTokens(viper.GetInt("openai.max_tokens")),
6363
anthropic.WithTemperature(float32(viper.GetFloat64("openai.temperature"))),
6464
anthropic.WithTopP(float32(viper.GetFloat64("openai.top_p"))),
65+
anthropic.WithProxyURL(viper.GetString("openai.proxy")),
66+
anthropic.WithSocksURL(viper.GetString("openai.socks")),
67+
anthropic.WithSkipVerify(viper.GetBool("openai.skip_verify")),
6568
)
6669
}
6770

provider/anthropic/anthropic.go

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,15 @@ package anthropic
22

33
import (
44
"context"
5+
"crypto/tls"
56
"encoding/json"
67
"errors"
78
"fmt"
9+
"net/http"
10+
"net/url"
811

912
"github.com/appleboy/CodeGPT/core"
13+
"golang.org/x/net/proxy"
1014

1115
"github.com/appleboy/com/convert"
1216
"github.com/liushuangls/go-anthropic/v2"
@@ -96,6 +100,22 @@ func (c *Client) GetSummaryPrefix(ctx context.Context, content string) (*core.Re
96100
}, nil
97101
}
98102

103+
// DefaultHeaderTransport is an http.RoundTripper that adds the given headers to
104+
type DefaultHeaderTransport struct {
105+
Origin http.RoundTripper
106+
Header http.Header
107+
}
108+
109+
// RoundTrip implements the http.RoundTripper interface.
110+
func (t *DefaultHeaderTransport) RoundTrip(req *http.Request) (*http.Response, error) {
111+
for key, values := range t.Header {
112+
for _, value := range values {
113+
req.Header.Add(key, value)
114+
}
115+
}
116+
return t.Origin.RoundTrip(req)
117+
}
118+
99119
func New(opts ...Option) (c *Client, err error) {
100120
// Create a new config object with the given options.
101121
cfg := newConfig(opts...)
@@ -105,9 +125,40 @@ func New(opts ...Option) (c *Client, err error) {
105125
return nil, err
106126
}
107127

128+
// Create a new HTTP transport.
129+
tr := &http.Transport{}
130+
if cfg.skipVerify {
131+
tr.TLSClientConfig = &tls.Config{InsecureSkipVerify: true} //nolint:gosec
132+
}
133+
134+
// Create a new HTTP client with the specified timeout and proxy, if any.
135+
httpClient := http.DefaultClient
136+
137+
if cfg.proxyURL != "" {
138+
proxyURL, err := url.Parse(cfg.proxyURL)
139+
if err != nil {
140+
return nil, fmt.Errorf("can't parse the proxy URL: %s", err)
141+
}
142+
tr.Proxy = http.ProxyURL(proxyURL)
143+
} else if cfg.socksURL != "" {
144+
dialer, err := proxy.SOCKS5("tcp", cfg.socksURL, nil, proxy.Direct)
145+
if err != nil {
146+
return nil, fmt.Errorf("can't connect to the proxy: %s", err)
147+
}
148+
tr.DialContext = dialer.(proxy.ContextDialer).DialContext
149+
}
150+
151+
// Set the HTTP client to use the default header transport with the specified headers.
152+
httpClient.Transport = &DefaultHeaderTransport{
153+
Origin: tr,
154+
}
155+
108156
// Create a new client instance with the necessary fields.
109157
engine := &Client{
110-
client: anthropic.NewClient(cfg.apiKey),
158+
client: anthropic.NewClient(
159+
cfg.apiKey,
160+
anthropic.WithHTTPClient(httpClient),
161+
),
111162
model: cfg.model,
112163
maxTokens: cfg.maxTokens,
113164
temperature: cfg.temperature,

provider/anthropic/options.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,13 +81,37 @@ func WithTopP(val float32) Option {
8181
})
8282
}
8383

84+
// WithProxyURL is a function that returns an Option, which sets the proxyURL field of the config struct.
85+
func WithProxyURL(val string) Option {
86+
return optionFunc(func(c *config) {
87+
c.proxyURL = val
88+
})
89+
}
90+
91+
// WithSocksURL is a function that returns an Option, which sets the socksURL field of the config struct.
92+
func WithSocksURL(val string) Option {
93+
return optionFunc(func(c *config) {
94+
c.socksURL = val
95+
})
96+
}
97+
98+
// WithSkipVerify returns a new Option that sets the skipVerify for the client configuration.
99+
func WithSkipVerify(val bool) Option {
100+
return optionFunc(func(c *config) {
101+
c.skipVerify = val
102+
})
103+
}
104+
84105
// config is a struct that stores configuration options for the instrumentation.
85106
type config struct {
86107
apiKey string
87108
model anthropic.Model
88109
maxTokens int
89110
temperature float32
90111
topP float32
112+
proxyURL string
113+
socksURL string
114+
skipVerify bool
91115
}
92116

93117
// valid checks whether a config object is valid, returning an error if it is not.

0 commit comments

Comments
 (0)