fix(provider): normalize anthropic model ids for API key path
This commit is contained in:
parent
4a8a2e9c23
commit
86eb07752d
2 changed files with 62 additions and 3 deletions
|
|
@ -428,12 +428,20 @@ func serializeMessages(messages []Message) []any {
|
|||
}
|
||||
|
||||
func normalizeModel(model, apiBase string) string {
|
||||
before, after, ok := strings.Cut(model, "/")
|
||||
if !ok {
|
||||
lowerBase := strings.ToLower(apiBase)
|
||||
if strings.Contains(lowerBase, "openrouter.ai") {
|
||||
return model
|
||||
}
|
||||
|
||||
if strings.Contains(strings.ToLower(apiBase), "openrouter.ai") {
|
||||
if strings.Contains(lowerBase, "api.anthropic.com") {
|
||||
if _, after, ok := strings.Cut(model, "/"); ok {
|
||||
model = after
|
||||
}
|
||||
return strings.ReplaceAll(model, ".", "-")
|
||||
}
|
||||
|
||||
before, after, ok := strings.Cut(model, "/")
|
||||
if !ok {
|
||||
return model
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -514,6 +514,12 @@ func TestNormalizeModel_UsesAPIBase(t *testing.T) {
|
|||
if got := normalizeModel("deepseek/deepseek-chat", "https://api.deepseek.com/v1"); got != "deepseek-chat" {
|
||||
t.Fatalf("normalizeModel(deepseek) = %q, want %q", got, "deepseek-chat")
|
||||
}
|
||||
if got := normalizeModel("claude-sonnet-4.6", "https://api.anthropic.com/v1"); got != "claude-sonnet-4-6" {
|
||||
t.Fatalf("normalizeModel(anthropic plain) = %q, want %q", got, "claude-sonnet-4-6")
|
||||
}
|
||||
if got := normalizeModel("anthropic/claude-sonnet-4.6", "https://api.anthropic.com/v1"); got != "claude-sonnet-4-6" {
|
||||
t.Fatalf("normalizeModel(anthropic prefixed) = %q, want %q", got, "claude-sonnet-4-6")
|
||||
}
|
||||
if got := normalizeModel("openrouter/auto", "https://openrouter.ai/api/v1"); got != "openrouter/auto" {
|
||||
t.Fatalf("normalizeModel(openrouter) = %q, want %q", got, "openrouter/auto")
|
||||
}
|
||||
|
|
@ -525,6 +531,51 @@ func TestNormalizeModel_UsesAPIBase(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestProviderChat_NormalizesAnthropicModelForAnthropicAPIBase(t *testing.T) {
|
||||
var requestBody map[string]any
|
||||
|
||||
p := NewProvider("key", "https://api.anthropic.com/v1", "")
|
||||
p.httpClient.Transport = roundTripperFunc(func(r *http.Request) (*http.Response, error) {
|
||||
if r.URL.String() != "https://api.anthropic.com/v1/chat/completions" {
|
||||
t.Fatalf("request URL = %q, want %q", r.URL.String(), "https://api.anthropic.com/v1/chat/completions")
|
||||
}
|
||||
if err := json.NewDecoder(r.Body).Decode(&requestBody); err != nil {
|
||||
t.Fatalf("decode request body: %v", err)
|
||||
}
|
||||
resp := map[string]any{
|
||||
"choices": []map[string]any{
|
||||
{
|
||||
"message": map[string]any{"content": "ok"},
|
||||
"finish_reason": "stop",
|
||||
},
|
||||
},
|
||||
}
|
||||
data, err := json.Marshal(resp)
|
||||
if err != nil {
|
||||
t.Fatalf("marshal response: %v", err)
|
||||
}
|
||||
return &http.Response{
|
||||
StatusCode: http.StatusOK,
|
||||
Header: http.Header{"Content-Type": []string{"application/json"}},
|
||||
Body: io.NopCloser(bytes.NewReader(data)),
|
||||
}, nil
|
||||
})
|
||||
|
||||
_, err := p.Chat(
|
||||
t.Context(),
|
||||
[]Message{{Role: "user", Content: "hi"}},
|
||||
nil,
|
||||
"claude-sonnet-4.6",
|
||||
nil,
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatalf("Chat() error = %v", err)
|
||||
}
|
||||
if got := requestBody["model"]; got != "claude-sonnet-4-6" {
|
||||
t.Fatalf("request model = %v, want %q", got, "claude-sonnet-4-6")
|
||||
}
|
||||
}
|
||||
|
||||
func TestProvider_RequestTimeoutDefault(t *testing.T) {
|
||||
p := NewProviderWithMaxTokensFieldAndTimeout("key", "https://example.com/v1", "", "", 0)
|
||||
if p.httpClient.Timeout != defaultRequestTimeout {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue