Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions config.example.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,15 @@ ws-auth: false
# iflow:
# - "tstars2.0"

# Claude OAuth Model Aliases
# Define model aliases for Claude Code (OAuth) accounts. This allows you to use shorter
# or more convenient model names when making API requests with authenticated Claude accounts.
# Format: alias: upstream-model-name
# claude-oauth-model-aliases:
# claude-haiku-4-5: "claude-haiku-4-5-20251001" # Use "claude-haiku-4-5" as alias for the full model name
# claude-sonnet-latest: "claude-sonnet-4-5-20250929"
# claude-opus-latest: "claude-opus-4-20250514"

# Optional payload configuration
# payload:
# default: # Default rules only set parameters when they are missing in the payload.
Expand Down
4 changes: 4 additions & 0 deletions internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,10 @@ type Config struct {
// OAuthExcludedModels defines per-provider global model exclusions applied to OAuth/file-backed auth entries.
OAuthExcludedModels map[string][]string `yaml:"oauth-excluded-models,omitempty" json:"oauth-excluded-models,omitempty"`

// ClaudeOAuthModelAliases defines model aliases for Claude OAuth (Claude Code) accounts.
// Maps alias names to upstream model names for routing.
ClaudeOAuthModelAliases map[string]string `yaml:"claude-oauth-model-aliases,omitempty" json:"claude-oauth-model-aliases,omitempty"`

// Payload defines default and override rules for provider payload parameters.
Payload PayloadConfig `yaml:"payload" json:"payload"`

Expand Down
30 changes: 30 additions & 0 deletions internal/runtime/executor/claude_executor.go
Original file line number Diff line number Diff line change
Expand Up @@ -505,6 +505,10 @@ func (e *ClaudeExecutor) resolveUpstreamModel(alias string, auth *cliproxyauth.A

entry := e.resolveClaudeConfig(auth)
if entry == nil {
// Check for OAuth model aliases (for Claude Code OAuth accounts)
if e.cfg != nil && auth != nil && strings.EqualFold(auth.Provider, "claude") {
return e.resolveOAuthModelAlias(trimmed)
}
return ""
}

Expand Down Expand Up @@ -539,6 +543,32 @@ func (e *ClaudeExecutor) resolveUpstreamModel(alias string, auth *cliproxyauth.A
}
}
}

// If no match in API key config, check OAuth aliases as fallback
if e.cfg != nil {
return e.resolveOAuthModelAlias(trimmed)
}

return ""
}

// resolveOAuthModelAlias resolves a model alias using the global Claude OAuth model aliases configuration.
// This supports aliasing for Claude Code (OAuth) accounts where API key config is not available.
func (e *ClaudeExecutor) resolveOAuthModelAlias(alias string) string {
if e.cfg == nil || len(e.cfg.ClaudeOAuthModelAliases) == 0 {
return ""
}

// Case-insensitive lookup for alias
aliasLower := strings.ToLower(alias)
for configuredAlias, upstream := range e.cfg.ClaudeOAuthModelAliases {
if strings.TrimSpace(configuredAlias) == "" {
continue
}
if strings.ToLower(strings.TrimSpace(configuredAlias)) == aliasLower {
return strings.TrimSpace(upstream)
}
}
return ""
}

Expand Down
45 changes: 45 additions & 0 deletions sdk/cliproxy/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -737,6 +737,10 @@ func (s *Service) registerModelsForAuth(a *coreauth.Auth) {
excluded = entry.ExcludedModels
}
}
// Add OAuth model aliases for Claude Code accounts
if oauthAliases := s.buildClaudeOAuthAliasModels(); len(oauthAliases) > 0 {
models = append(models, oauthAliases...)
}
models = applyExcludedModels(models, excluded)
case "codex":
models = registry.GetOpenAIModels()
Expand Down Expand Up @@ -1179,3 +1183,44 @@ func buildClaudeConfigModels(entry *config.ClaudeKey) []*ModelInfo {
}
return out
}

// buildClaudeOAuthAliasModels builds model info entries from global Claude OAuth model aliases configuration.
// This allows aliasing models for Claude Code (OAuth) accounts where API key config is not available.
func (s *Service) buildClaudeOAuthAliasModels() []*ModelInfo {
if s.cfg == nil || len(s.cfg.ClaudeOAuthModelAliases) == 0 {
return nil
}

now := time.Now().Unix()
out := make([]*ModelInfo, 0, len(s.cfg.ClaudeOAuthModelAliases))
seen := make(map[string]struct{}, len(s.cfg.ClaudeOAuthModelAliases))

for alias, upstream := range s.cfg.ClaudeOAuthModelAliases {
alias = strings.TrimSpace(alias)
upstream = strings.TrimSpace(upstream)

if alias == "" || upstream == "" {
continue
}

key := strings.ToLower(alias)
if _, exists := seen[key]; exists {
continue
}
seen[key] = struct{}{}

// Use the upstream model as display name
display := upstream

out = append(out, &ModelInfo{
ID: alias,
Object: "model",
Created: now,
OwnedBy: "claude",
Type: "claude",
DisplayName: display,
})
}

return out
}