fix(providers): address review comments in anthropic-messages provider

- fix normalizeBaseURL edge case that incorrectly appends /v1 to URLs already containing /v1 path (e.g., https://api.example.com/v1/proxy)
- remove dead code for apiBase empty check as normalizeBaseURL() always provides a default value
- update test to use proper constructor instead of direct struct initialization
- add detailed comments explaining the URL normalization logic

Resolves review comments on PR #1284
This commit is contained in:
ZaneTung 2026-03-11 11:08:47 +08:00
parent 4e52511704
commit ddfa437f9c
2 changed files with 19 additions and 23 deletions

View file

@ -73,10 +73,6 @@ func (p *Provider) Chat(
model string,
options map[string]any,
) (*LLMResponse, error) {
if p.apiBase == "" {
return nil, fmt.Errorf("API base not configured")
}
if p.apiKey == "" {
return nil, fmt.Errorf("API key not configured")
}
@ -323,19 +319,30 @@ func parseResponseBody(body []byte) (*LLMResponse, error) {
}
// normalizeBaseURL ensures the base URL is properly formatted.
// It removes /v1 suffix if present (to avoid duplication) and always appends /v1.
// This handles edge cases like "https://api.example.com/v1/proxy" correctly.
func normalizeBaseURL(apiBase string) string {
base := strings.TrimSpace(apiBase)
if base == "" {
return defaultBaseURL
}
// Remove trailing slashes
base = strings.TrimRight(base, "/")
// Add /v1 if not present
if !strings.HasSuffix(base, "/v1") {
base = base + "/v1"
// Remove /v1 suffix if present (will be re-added)
// This prevents duplication for URLs like "https://api.example.com/v1/proxy"
if before, ok := strings.CutSuffix(base, "/v1"); ok {
base = before
}
return base
// Ensure we don't have an empty string after cutting
if base == "" {
return defaultBaseURL
}
// Add /v1 suffix (required by Anthropic Messages API)
return base + "/v1"
}
// Helper functions for type conversion

View file

@ -413,26 +413,18 @@ func TestGetDefaultModel(t *testing.T) {
}
}
// Mock HTTP server test for integration testing
// TestProviderChatErrors tests error handling in Chat.
// Note: apiBase check removed as it's dead code - normalizeBaseURL() always provides a default.
func TestProviderChatErrors(t *testing.T) {
tests := []struct {
name string
apiKey string
apiBase string
messages []Message
wantErrMsg string
}{
{
name: "missing API base",
apiKey: "test-key",
apiBase: "",
messages: []Message{{Role: "user", Content: "Test"}},
wantErrMsg: "API base not configured",
},
{
name: "missing API key",
apiKey: "",
apiBase: "https://api.example.com",
messages: []Message{{Role: "user", Content: "Test"}},
wantErrMsg: "API key not configured",
},
@ -440,11 +432,8 @@ func TestProviderChatErrors(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// Create provider with empty apiBase to trigger error
provider := &Provider{
apiKey: tt.apiKey,
apiBase: tt.apiBase,
}
// Create provider using constructor to ensure proper initialization
provider := NewProvider(tt.apiKey, "https://api.example.com")
_, err := provider.Chat(context.Background(), tt.messages, nil, "test-model", nil)
if err == nil {