mirror of
https://github.com/tiennm99/goclaw.git
synced 2026-10-03 07:12:50 +00:00
feat(providers): support custom base URL for Anthropic provider (#16)
Allow overriding the Anthropic API base URL via GOCLAW_ANTHROPIC_BASE_URL env var, config JSON, or DB provider record. Enables use of Anthropic- compatible proxies and custom endpoints. Also adds Makefile shortcuts for docker compose (up/down/logs).
This commit is contained in:
1 parent
7450e7014a
commit
4c67dff24d
6 files changed
+31
-5
No files matched your search
@@ -2,7 +2,7 @@ VERSION ?= $(shell git describe --tags --always --dirty 2>/dev/null || echo dev)
|
||||
LDFLAGS = -s -w -X github.com/nextlevelbuilder/goclaw/cmd.Version=$(VERSION)
|
||||
BINARY = goclaw
|
||||
|
||||
.PHONY: build run clean version
|
||||
.PHONY: build run clean version up down logs
|
||||
|
||||
build:
|
||||
CGO_ENABLED=0 go build -ldflags="$(LDFLAGS)" -o $(BINARY) .
|
||||
@@ -15,3 +15,14 @@ clean:
|
||||
|
||||
version:
|
||||
@echo $(VERSION)
|
||||
|
||||
COMPOSE = docker compose -f docker-compose.yml -f docker-compose.managed.yml -f docker-compose.selfservice.yml
|
||||
|
||||
up:
|
||||
$(COMPOSE) up -d --build
|
||||
|
||||
down:
|
||||
$(COMPOSE) down
|
||||
|
||||
logs:
|
||||
$(COMPOSE) logs -f goclaw
|
||||
@@ -11,7 +11,8 @@ import (
|
||||
|
||||
func registerProviders(registry *providers.Registry, cfg *config.Config) {
|
||||
if cfg.Providers.Anthropic.APIKey != "" {
|
||||
registry.Register(providers.NewAnthropicProvider(cfg.Providers.Anthropic.APIKey))
|
||||
registry.Register(providers.NewAnthropicProvider(cfg.Providers.Anthropic.APIKey,
|
||||
providers.WithAnthropicBaseURL(cfg.Providers.Anthropic.APIBase)))
|
||||
slog.Info("registered provider", "name", "anthropic")
|
||||
}
|
||||
|
||||
@@ -81,7 +82,8 @@ func registerProvidersFromDB(registry *providers.Registry, provStore store.Provi
|
||||
continue
|
||||
}
|
||||
if p.ProviderType == store.ProviderAnthropicNative {
|
||||
registry.Register(providers.NewAnthropicProvider(p.APIKey))
|
||||
registry.Register(providers.NewAnthropicProvider(p.APIKey,
|
||||
providers.WithAnthropicBaseURL(p.APIBase)))
|
||||
} else {
|
||||
prov := providers.NewOpenAIProvider(p.Name, p.APIKey, p.APIBase, "")
|
||||
if p.ProviderType == store.ProviderMiniMax {
|
||||
|
||||
@@ -33,6 +33,7 @@ services:
|
||||
- GOCLAW_MODEL=${GOCLAW_MODEL:-}
|
||||
- GOCLAW_OPENROUTER_API_KEY=${GOCLAW_OPENROUTER_API_KEY:-}
|
||||
- GOCLAW_ANTHROPIC_API_KEY=${GOCLAW_ANTHROPIC_API_KEY:-}
|
||||
- GOCLAW_ANTHROPIC_BASE_URL=${GOCLAW_ANTHROPIC_BASE_URL:-}
|
||||
- GOCLAW_OPENAI_API_KEY=${GOCLAW_OPENAI_API_KEY:-}
|
||||
- GOCLAW_MINIMAX_API_KEY=${GOCLAW_MINIMAX_API_KEY:-}
|
||||
- GOCLAW_GROQ_API_KEY=${GOCLAW_GROQ_API_KEY:-}
|
||||
|
||||
@@ -94,6 +94,7 @@ func (c *Config) applyEnvOverrides() {
|
||||
}
|
||||
}
|
||||
envStr("GOCLAW_ANTHROPIC_API_KEY", &c.Providers.Anthropic.APIKey)
|
||||
envStr("GOCLAW_ANTHROPIC_BASE_URL", &c.Providers.Anthropic.APIBase)
|
||||
envStr("GOCLAW_OPENAI_API_KEY", &c.Providers.OpenAI.APIKey)
|
||||
envStr("GOCLAW_OPENROUTER_API_KEY", &c.Providers.OpenRouter.APIKey)
|
||||
envStr("GOCLAW_GROQ_API_KEY", &c.Providers.Groq.APIKey)
|
||||
|
||||
@@ -65,7 +65,8 @@ func (h *ProvidersHandler) registerInMemory(p *store.LLMProviderData) {
|
||||
return
|
||||
}
|
||||
if p.ProviderType == store.ProviderAnthropicNative {
|
||||
h.providerReg.Register(providers.NewAnthropicProvider(p.APIKey))
|
||||
h.providerReg.Register(providers.NewAnthropicProvider(p.APIKey,
|
||||
providers.WithAnthropicBaseURL(p.APIBase)))
|
||||
} else {
|
||||
prov := providers.NewOpenAIProvider(p.Name, p.APIKey, p.APIBase, "")
|
||||
if p.ProviderType == store.ProviderMiniMax {
|
||||
|
||||
@@ -21,6 +21,7 @@ const (
|
||||
// AnthropicProvider implements Provider using the Anthropic Claude API via net/http.
|
||||
type AnthropicProvider struct {
|
||||
apiKey string
|
||||
baseURL string
|
||||
defaultModel string
|
||||
client *http.Client
|
||||
retryConfig RetryConfig
|
||||
@@ -30,6 +31,7 @@ type AnthropicProvider struct {
|
||||
func NewAnthropicProvider(apiKey string, opts ...AnthropicOption) *AnthropicProvider {
|
||||
p := &AnthropicProvider{
|
||||
apiKey: apiKey,
|
||||
baseURL: anthropicAPIBase,
|
||||
defaultModel: defaultClaudeModel,
|
||||
client: &http.Client{Timeout: 120 * time.Second},
|
||||
retryConfig: DefaultRetryConfig(),
|
||||
@@ -46,6 +48,14 @@ func WithAnthropicModel(model string) AnthropicOption {
|
||||
return func(p *AnthropicProvider) { p.defaultModel = model }
|
||||
}
|
||||
|
||||
func WithAnthropicBaseURL(baseURL string) AnthropicOption {
|
||||
return func(p *AnthropicProvider) {
|
||||
if baseURL != "" {
|
||||
p.baseURL = strings.TrimRight(baseURL, "/")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (p *AnthropicProvider) Name() string { return "anthropic" }
|
||||
func (p *AnthropicProvider) DefaultModel() string { return p.defaultModel }
|
||||
|
||||
@@ -331,7 +341,7 @@ func (p *AnthropicProvider) doRequest(ctx context.Context, body interface{}) (io
|
||||
return nil, fmt.Errorf("anthropic: marshal request: %w", err)
|
||||
}
|
||||
|
||||
httpReq, err := http.NewRequestWithContext(ctx, "POST", anthropicAPIBase+"/messages", bytes.NewReader(data))
|
||||
httpReq, err := http.NewRequestWithContext(ctx, "POST", p.baseURL+"/messages", bytes.NewReader(data))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("anthropic: create request: %w", err)
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user