mirror of
https://github.com/Wei-Shaw/sub2api.git
synced 2026-10-16 07:33:06 +08:00
feat: support Claude Sonnet 5.5
This commit is contained in:
@@ -190,6 +190,12 @@ var DefaultModels = []Model{
|
||||
DisplayName: "Claude Opus 5",
|
||||
CreatedAt: "2026-07-25T00:00:00Z",
|
||||
},
|
||||
{
|
||||
ID: "claude-sonnet-5-5",
|
||||
Type: "model",
|
||||
DisplayName: "Claude Sonnet 5.5",
|
||||
CreatedAt: "2026-09-28T00:00:00Z",
|
||||
},
|
||||
{
|
||||
ID: "claude-sonnet-5",
|
||||
Type: "model",
|
||||
|
||||
@@ -30,3 +30,16 @@ func TestDefaultModelsContainsOpus55(t *testing.T) {
|
||||
}
|
||||
t.Fatal("claude-opus-5-5 missing")
|
||||
}
|
||||
|
||||
func TestDefaultModelsContainsSonnet55(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
for _, model := range DefaultModels {
|
||||
if model.ID == "claude-sonnet-5-5" {
|
||||
require.Equal(t, "Claude Sonnet 5.5", model.DisplayName)
|
||||
require.Equal(t, "2026-09-28T00:00:00Z", model.CreatedAt)
|
||||
return
|
||||
}
|
||||
}
|
||||
t.Fatal("claude-sonnet-5-5 missing from DefaultModels")
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ var effortFamilies = []struct {
|
||||
{family: "claude-mythos-5", levels: effortLowMediumHighXHighMax},
|
||||
{family: "claude-fable-5", levels: effortLowMediumHighXHighMax},
|
||||
{family: "claude-sonnet-4-6", levels: effortLowMediumHighMax},
|
||||
{family: "claude-sonnet-5-5", levels: effortLowMediumHighXHighMax},
|
||||
{family: "claude-sonnet-5", levels: effortLowMediumHighXHighMax},
|
||||
{family: "claude-opus-4-8", levels: effortLowMediumHighXHighMax},
|
||||
{family: "claude-opus-4-7", levels: effortLowMediumHighXHighMax},
|
||||
@@ -45,19 +46,30 @@ func IsOpus55(model string) bool {
|
||||
return normalizeEffortModelID(model) == "claude-opus-5-5"
|
||||
}
|
||||
|
||||
// IsSonnet55 identifies the fixed Sonnet 5.5 ID after provider/local suffix normalization.
|
||||
func IsSonnet55(model string) bool {
|
||||
return normalizeEffortModelID(model) == "claude-sonnet-5-5"
|
||||
}
|
||||
|
||||
func normalizeEffortModelID(model string) string {
|
||||
id := strings.ToLower(strings.TrimSpace(model))
|
||||
id = strings.TrimPrefix(id, "models/")
|
||||
if slash := strings.IndexByte(id, '/'); slash >= 0 {
|
||||
id = strings.TrimPrefix(strings.TrimSpace(id[slash+1:]), "models/")
|
||||
}
|
||||
for _, prefix := range []string{"us.", "eu.", "apac.", "jp.", "au.", "us-gov.", "global."} {
|
||||
id = strings.TrimPrefix(id, prefix)
|
||||
}
|
||||
id = strings.TrimPrefix(id, "anthropic.")
|
||||
id = strings.TrimSuffix(id, "-thinking")
|
||||
// OpenRouter uses a dotted minor version for this exact Opus 5.5 ID.
|
||||
// Normalize it before effort, thinking, and billing family lookups.
|
||||
// OpenRouter uses dotted minor versions for some models. Normalize them
|
||||
// before effort, thinking, and billing family lookups.
|
||||
if id == "claude-opus-5.5" {
|
||||
id = "claude-opus-5-5"
|
||||
}
|
||||
if id == "claude-sonnet-5.5" {
|
||||
id = "claude-sonnet-5-5"
|
||||
}
|
||||
if mapped, ok := ModelIDReverseOverrides[id]; ok {
|
||||
id = mapped
|
||||
}
|
||||
|
||||
@@ -17,6 +17,8 @@ func TestEffortLevelsForModel(t *testing.T) {
|
||||
{model: "anthropic/claude-sonnet-4-6", want: []string{"low", "medium", "high", "max"}},
|
||||
{model: "claude-opus-5", want: []string{"low", "medium", "high", "xhigh", "max"}},
|
||||
{model: "anthropic/claude-opus-5.5", want: []string{"low", "medium", "high", "xhigh", "max"}},
|
||||
{model: "claude-sonnet-5-5", want: []string{"low", "medium", "high", "xhigh", "max"}},
|
||||
{model: "us.anthropic.claude-sonnet-5-5", want: []string{"low", "medium", "high", "xhigh", "max"}},
|
||||
{model: "claude-opus-4-5-20251101", want: []string{"low", "medium", "high"}},
|
||||
{model: "claude-haiku-4-5-20251001", want: nil},
|
||||
{model: "gpt-5.6", want: nil},
|
||||
@@ -38,3 +40,20 @@ func TestIsOpus55OpenRouterExactAlias(t *testing.T) {
|
||||
require.False(t, IsOpus55(model), model)
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsSonnet55(t *testing.T) {
|
||||
t.Parallel()
|
||||
for _, model := range []string{
|
||||
"claude-sonnet-5-5",
|
||||
"anthropic/claude-sonnet-5.5",
|
||||
"anthropic.claude-sonnet-5-5",
|
||||
"us.anthropic.claude-sonnet-5-5",
|
||||
"us-gov.anthropic.claude-sonnet-5-5",
|
||||
"global.anthropic.claude-sonnet-5-5-thinking",
|
||||
} {
|
||||
require.True(t, IsSonnet55(model), model)
|
||||
}
|
||||
for _, model := range []string{"claude-sonnet-5", "claude-sonnet-5-5-preview", "claude-opus-5-5"} {
|
||||
require.False(t, IsSonnet55(model), model)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user