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 {
|
func normalizeModel(model, apiBase string) string {
|
||||||
before, after, ok := strings.Cut(model, "/")
|
lowerBase := strings.ToLower(apiBase)
|
||||||
if !ok {
|
if strings.Contains(lowerBase, "openrouter.ai") {
|
||||||
return model
|
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
|
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" {
|
if got := normalizeModel("deepseek/deepseek-chat", "https://api.deepseek.com/v1"); got != "deepseek-chat" {
|
||||||
t.Fatalf("normalizeModel(deepseek) = %q, want %q", 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" {
|
if got := normalizeModel("openrouter/auto", "https://openrouter.ai/api/v1"); got != "openrouter/auto" {
|
||||||
t.Fatalf("normalizeModel(openrouter) = %q, want %q", 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) {
|
func TestProvider_RequestTimeoutDefault(t *testing.T) {
|
||||||
p := NewProviderWithMaxTokensFieldAndTimeout("key", "https://example.com/v1", "", "", 0)
|
p := NewProviderWithMaxTokensFieldAndTimeout("key", "https://example.com/v1", "", "", 0)
|
||||||
if p.httpClient.Timeout != defaultRequestTimeout {
|
if p.httpClient.Timeout != defaultRequestTimeout {
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue