mirror of
https://github.com/router-for-me/CLIProxyAPIPlus.git
synced 2026-03-21 16:40:22 +00:00
fix: add default copilot claude model aliases for oauth routing
This commit is contained in:
@@ -759,22 +759,24 @@ func (cfg *Config) SanitizeOAuthModelAlias() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Inject default Kiro aliases if no user-configured kiro aliases exist
|
// Inject channel defaults when the channel is absent in user config.
|
||||||
|
// Presence is checked case-insensitively and includes explicit nil/empty markers.
|
||||||
if cfg.OAuthModelAlias == nil {
|
if cfg.OAuthModelAlias == nil {
|
||||||
cfg.OAuthModelAlias = make(map[string][]OAuthModelAlias)
|
cfg.OAuthModelAlias = make(map[string][]OAuthModelAlias)
|
||||||
}
|
}
|
||||||
if _, hasKiro := cfg.OAuthModelAlias["kiro"]; !hasKiro {
|
hasChannel := func(channel string) bool {
|
||||||
// Check case-insensitive too
|
|
||||||
found := false
|
|
||||||
for k := range cfg.OAuthModelAlias {
|
for k := range cfg.OAuthModelAlias {
|
||||||
if strings.EqualFold(strings.TrimSpace(k), "kiro") {
|
if strings.EqualFold(strings.TrimSpace(k), channel) {
|
||||||
found = true
|
return true
|
||||||
break
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !found {
|
return false
|
||||||
cfg.OAuthModelAlias["kiro"] = defaultKiroAliases()
|
}
|
||||||
}
|
if !hasChannel("kiro") {
|
||||||
|
cfg.OAuthModelAlias["kiro"] = defaultKiroAliases()
|
||||||
|
}
|
||||||
|
if !hasChannel("github-copilot") {
|
||||||
|
cfg.OAuthModelAlias["github-copilot"] = defaultGitHubCopilotAliases()
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(cfg.OAuthModelAlias) == 0 {
|
if len(cfg.OAuthModelAlias) == 0 {
|
||||||
|
|||||||
@@ -42,6 +42,21 @@ func defaultKiroAliases() []OAuthModelAlias {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// defaultGitHubCopilotAliases returns default oauth-model-alias entries that
|
||||||
|
// expose Claude hyphen-style IDs for GitHub Copilot Claude models.
|
||||||
|
// This keeps compatibility with clients (e.g. Claude Code) that use
|
||||||
|
// Anthropic-style model IDs like "claude-opus-4-6".
|
||||||
|
func defaultGitHubCopilotAliases() []OAuthModelAlias {
|
||||||
|
return []OAuthModelAlias{
|
||||||
|
{Name: "claude-haiku-4.5", Alias: "claude-haiku-4-5", Fork: true},
|
||||||
|
{Name: "claude-opus-4.1", Alias: "claude-opus-4-1", Fork: true},
|
||||||
|
{Name: "claude-opus-4.5", Alias: "claude-opus-4-5", Fork: true},
|
||||||
|
{Name: "claude-opus-4.6", Alias: "claude-opus-4-6", Fork: true},
|
||||||
|
{Name: "claude-sonnet-4.5", Alias: "claude-sonnet-4-5", Fork: true},
|
||||||
|
{Name: "claude-sonnet-4.6", Alias: "claude-sonnet-4-6", Fork: true},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// defaultAntigravityAliases returns the default oauth-model-alias configuration
|
// defaultAntigravityAliases returns the default oauth-model-alias configuration
|
||||||
// for the antigravity channel when neither field exists.
|
// for the antigravity channel when neither field exists.
|
||||||
func defaultAntigravityAliases() []OAuthModelAlias {
|
func defaultAntigravityAliases() []OAuthModelAlias {
|
||||||
|
|||||||
@@ -107,6 +107,44 @@ func TestSanitizeOAuthModelAlias_InjectsDefaultKiroAliases(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestSanitizeOAuthModelAlias_InjectsDefaultGitHubCopilotAliases(t *testing.T) {
|
||||||
|
cfg := &Config{
|
||||||
|
OAuthModelAlias: map[string][]OAuthModelAlias{
|
||||||
|
"codex": {
|
||||||
|
{Name: "gpt-5", Alias: "g5"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
cfg.SanitizeOAuthModelAlias()
|
||||||
|
|
||||||
|
copilotAliases := cfg.OAuthModelAlias["github-copilot"]
|
||||||
|
if len(copilotAliases) == 0 {
|
||||||
|
t.Fatal("expected default github-copilot aliases to be injected")
|
||||||
|
}
|
||||||
|
|
||||||
|
aliasSet := make(map[string]bool, len(copilotAliases))
|
||||||
|
for _, a := range copilotAliases {
|
||||||
|
aliasSet[a.Alias] = true
|
||||||
|
if !a.Fork {
|
||||||
|
t.Fatalf("expected all default github-copilot aliases to have fork=true, got fork=false for %q", a.Alias)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expectedAliases := []string{
|
||||||
|
"claude-haiku-4-5",
|
||||||
|
"claude-opus-4-1",
|
||||||
|
"claude-opus-4-5",
|
||||||
|
"claude-opus-4-6",
|
||||||
|
"claude-sonnet-4-5",
|
||||||
|
"claude-sonnet-4-6",
|
||||||
|
}
|
||||||
|
for _, expected := range expectedAliases {
|
||||||
|
if !aliasSet[expected] {
|
||||||
|
t.Fatalf("expected default github-copilot alias %q to be present", expected)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestSanitizeOAuthModelAlias_DoesNotOverrideUserKiroAliases(t *testing.T) {
|
func TestSanitizeOAuthModelAlias_DoesNotOverrideUserKiroAliases(t *testing.T) {
|
||||||
// When user has configured kiro aliases, defaults should NOT be injected
|
// When user has configured kiro aliases, defaults should NOT be injected
|
||||||
cfg := &Config{
|
cfg := &Config{
|
||||||
@@ -128,6 +166,26 @@ func TestSanitizeOAuthModelAlias_DoesNotOverrideUserKiroAliases(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestSanitizeOAuthModelAlias_DoesNotOverrideUserGitHubCopilotAliases(t *testing.T) {
|
||||||
|
cfg := &Config{
|
||||||
|
OAuthModelAlias: map[string][]OAuthModelAlias{
|
||||||
|
"github-copilot": {
|
||||||
|
{Name: "claude-opus-4.6", Alias: "my-opus", Fork: true},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
cfg.SanitizeOAuthModelAlias()
|
||||||
|
|
||||||
|
copilotAliases := cfg.OAuthModelAlias["github-copilot"]
|
||||||
|
if len(copilotAliases) != 1 {
|
||||||
|
t.Fatalf("expected 1 user-configured github-copilot alias, got %d", len(copilotAliases))
|
||||||
|
}
|
||||||
|
if copilotAliases[0].Alias != "my-opus" {
|
||||||
|
t.Fatalf("expected user alias to be preserved, got %q", copilotAliases[0].Alias)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestSanitizeOAuthModelAlias_DoesNotReinjectAfterExplicitDeletion(t *testing.T) {
|
func TestSanitizeOAuthModelAlias_DoesNotReinjectAfterExplicitDeletion(t *testing.T) {
|
||||||
// When user explicitly deletes kiro aliases (key exists with nil value),
|
// When user explicitly deletes kiro aliases (key exists with nil value),
|
||||||
// defaults should NOT be re-injected on subsequent sanitize calls (#222).
|
// defaults should NOT be re-injected on subsequent sanitize calls (#222).
|
||||||
@@ -154,6 +212,24 @@ func TestSanitizeOAuthModelAlias_DoesNotReinjectAfterExplicitDeletion(t *testing
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestSanitizeOAuthModelAlias_GitHubCopilotDoesNotReinjectAfterExplicitDeletion(t *testing.T) {
|
||||||
|
cfg := &Config{
|
||||||
|
OAuthModelAlias: map[string][]OAuthModelAlias{
|
||||||
|
"github-copilot": nil, // explicitly deleted
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
cfg.SanitizeOAuthModelAlias()
|
||||||
|
|
||||||
|
copilotAliases := cfg.OAuthModelAlias["github-copilot"]
|
||||||
|
if len(copilotAliases) != 0 {
|
||||||
|
t.Fatalf("expected github-copilot aliases to remain empty after explicit deletion, got %d aliases", len(copilotAliases))
|
||||||
|
}
|
||||||
|
if _, exists := cfg.OAuthModelAlias["github-copilot"]; !exists {
|
||||||
|
t.Fatal("expected github-copilot key to be preserved as nil marker after sanitization")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestSanitizeOAuthModelAlias_DoesNotReinjectAfterExplicitDeletionEmpty(t *testing.T) {
|
func TestSanitizeOAuthModelAlias_DoesNotReinjectAfterExplicitDeletionEmpty(t *testing.T) {
|
||||||
// Same as above but with empty slice instead of nil (PUT with empty body).
|
// Same as above but with empty slice instead of nil (PUT with empty body).
|
||||||
cfg := &Config{
|
cfg := &Config{
|
||||||
|
|||||||
@@ -90,3 +90,26 @@ func TestApplyOAuthModelAlias_ForkAddsMultipleAliases(t *testing.T) {
|
|||||||
t.Fatalf("expected forked model name %q, got %q", "models/g5-2", out[2].Name)
|
t.Fatalf("expected forked model name %q, got %q", "models/g5-2", out[2].Name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestApplyOAuthModelAlias_DefaultGitHubCopilotAliasViaSanitize(t *testing.T) {
|
||||||
|
cfg := &config.Config{}
|
||||||
|
cfg.SanitizeOAuthModelAlias()
|
||||||
|
|
||||||
|
models := []*ModelInfo{
|
||||||
|
{ID: "claude-opus-4.6", Name: "models/claude-opus-4.6"},
|
||||||
|
}
|
||||||
|
|
||||||
|
out := applyOAuthModelAlias(cfg, "github-copilot", "oauth", models)
|
||||||
|
if len(out) != 2 {
|
||||||
|
t.Fatalf("expected 2 models (original + default alias), got %d", len(out))
|
||||||
|
}
|
||||||
|
if out[0].ID != "claude-opus-4.6" {
|
||||||
|
t.Fatalf("expected first model id %q, got %q", "claude-opus-4.6", out[0].ID)
|
||||||
|
}
|
||||||
|
if out[1].ID != "claude-opus-4-6" {
|
||||||
|
t.Fatalf("expected second model id %q, got %q", "claude-opus-4-6", out[1].ID)
|
||||||
|
}
|
||||||
|
if out[1].Name != "models/claude-opus-4-6" {
|
||||||
|
t.Fatalf("expected aliased model name %q, got %q", "models/claude-opus-4-6", out[1].Name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user