From 70fdd70b84581bcd7c85e5607e997eee6f2676b5 Mon Sep 17 00:00:00 2001 From: hkfires <10558748+hkfires@users.noreply.github.com> Date: Tue, 30 Dec 2025 13:35:22 +0800 Subject: [PATCH] refactor(cliproxy): extract generic buildConfigModels function for model info generation --- internal/config/config.go | 9 ++ internal/config/vertex_compat.go | 3 + sdk/cliproxy/service.go | 167 ++++++++----------------------- 3 files changed, 55 insertions(+), 124 deletions(-) diff --git a/internal/config/config.go b/internal/config/config.go index 0cde69c7..668764d9 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -268,6 +268,9 @@ type ClaudeModel struct { Alias string `yaml:"alias" json:"alias"` } +func (m ClaudeModel) GetName() string { return m.Name } +func (m ClaudeModel) GetAlias() string { return m.Alias } + // CodexKey represents the configuration for a Codex API key, // including the API key itself and an optional base URL for the API endpoint. type CodexKey struct { @@ -303,6 +306,9 @@ type CodexModel struct { Alias string `yaml:"alias" json:"alias"` } +func (m CodexModel) GetName() string { return m.Name } +func (m CodexModel) GetAlias() string { return m.Alias } + // GeminiKey represents the configuration for a Gemini API key, // including optional overrides for upstream base URL, proxy routing, and headers. type GeminiKey struct { @@ -337,6 +343,9 @@ type GeminiModel struct { Alias string `yaml:"alias" json:"alias"` } +func (m GeminiModel) GetName() string { return m.Name } +func (m GeminiModel) GetAlias() string { return m.Alias } + // OpenAICompatibility represents the configuration for OpenAI API compatibility // with external providers, allowing model aliases to be routed through OpenAI API format. type OpenAICompatibility struct { diff --git a/internal/config/vertex_compat.go b/internal/config/vertex_compat.go index a14f75bc..94e162b7 100644 --- a/internal/config/vertex_compat.go +++ b/internal/config/vertex_compat.go @@ -42,6 +42,9 @@ type VertexCompatModel struct { Alias string `yaml:"alias" json:"alias"` } +func (m VertexCompatModel) GetName() string { return m.Name } +func (m VertexCompatModel) GetAlias() string { return m.Alias } + // SanitizeVertexCompatKeys deduplicates and normalizes Vertex-compatible API key credentials. func (cfg *Config) SanitizeVertexCompatKeys() { if cfg == nil { diff --git a/sdk/cliproxy/service.go b/sdk/cliproxy/service.go index 4101bf22..043eedb7 100644 --- a/sdk/cliproxy/service.go +++ b/sdk/cliproxy/service.go @@ -1119,17 +1119,22 @@ func matchWildcard(pattern, value string) bool { return true } -func buildVertexCompatConfigModels(entry *config.VertexCompatKey) []*ModelInfo { - if entry == nil || len(entry.Models) == 0 { +type modelEntry interface { + GetName() string + GetAlias() string +} + +func buildConfigModels[T modelEntry](models []T, ownedBy, modelType string) []*ModelInfo { + if len(models) == 0 { return nil } now := time.Now().Unix() - out := make([]*ModelInfo, 0, len(entry.Models)) - seen := make(map[string]struct{}, len(entry.Models)) - for i := range entry.Models { - model := entry.Models[i] - name := strings.TrimSpace(model.Name) - alias := strings.TrimSpace(model.Alias) + out := make([]*ModelInfo, 0, len(models)) + seen := make(map[string]struct{}, len(models)) + for i := range models { + model := models[i] + name := strings.TrimSpace(model.GetName()) + alias := strings.TrimSpace(model.GetAlias()) if alias == "" { alias = name } @@ -1149,14 +1154,42 @@ func buildVertexCompatConfigModels(entry *config.VertexCompatKey) []*ModelInfo { ID: alias, Object: "model", Created: now, - OwnedBy: "google", - Type: "vertex", + OwnedBy: ownedBy, + Type: modelType, DisplayName: display, }) } return out } +func buildVertexCompatConfigModels(entry *config.VertexCompatKey) []*ModelInfo { + if entry == nil { + return nil + } + return buildConfigModels(entry.Models, "google", "vertex") +} + +func buildGeminiConfigModels(entry *config.GeminiKey) []*ModelInfo { + if entry == nil { + return nil + } + return buildConfigModels(entry.Models, "google", "gemini") +} + +func buildClaudeConfigModels(entry *config.ClaudeKey) []*ModelInfo { + if entry == nil { + return nil + } + return buildConfigModels(entry.Models, "anthropic", "claude") +} + +func buildCodexConfigModels(entry *config.CodexKey) []*ModelInfo { + if entry == nil { + return nil + } + return buildConfigModels(entry.Models, "openai", "openai") +} + func rewriteModelInfoName(name, oldID, newID string) string { trimmed := strings.TrimSpace(name) if trimmed == "" { @@ -1243,117 +1276,3 @@ func applyOAuthModelMappings(cfg *config.Config, provider, authKind string, mode } return out } - -func buildGeminiConfigModels(entry *config.GeminiKey) []*ModelInfo { - if entry == nil || len(entry.Models) == 0 { - return nil - } - now := time.Now().Unix() - out := make([]*ModelInfo, 0, len(entry.Models)) - seen := make(map[string]struct{}, len(entry.Models)) - for i := range entry.Models { - model := entry.Models[i] - name := strings.TrimSpace(model.Name) - alias := strings.TrimSpace(model.Alias) - if alias == "" { - alias = name - } - if alias == "" { - continue - } - key := strings.ToLower(alias) - if _, exists := seen[key]; exists { - continue - } - seen[key] = struct{}{} - display := name - if display == "" { - display = alias - } - out = append(out, &ModelInfo{ - ID: alias, - Object: "model", - Created: now, - OwnedBy: "google", - Type: "gemini", - DisplayName: display, - }) - } - return out -} - -func buildClaudeConfigModels(entry *config.ClaudeKey) []*ModelInfo { - if entry == nil || len(entry.Models) == 0 { - return nil - } - now := time.Now().Unix() - out := make([]*ModelInfo, 0, len(entry.Models)) - seen := make(map[string]struct{}, len(entry.Models)) - for i := range entry.Models { - model := entry.Models[i] - name := strings.TrimSpace(model.Name) - alias := strings.TrimSpace(model.Alias) - if alias == "" { - alias = name - } - if alias == "" { - continue - } - key := strings.ToLower(alias) - if _, exists := seen[key]; exists { - continue - } - seen[key] = struct{}{} - display := name - if display == "" { - display = alias - } - out = append(out, &ModelInfo{ - ID: alias, - Object: "model", - Created: now, - OwnedBy: "anthropic", - Type: "claude", - DisplayName: display, - }) - } - return out -} - -func buildCodexConfigModels(entry *config.CodexKey) []*ModelInfo { - if entry == nil || len(entry.Models) == 0 { - return nil - } - now := time.Now().Unix() - out := make([]*ModelInfo, 0, len(entry.Models)) - seen := make(map[string]struct{}, len(entry.Models)) - for i := range entry.Models { - model := entry.Models[i] - name := strings.TrimSpace(model.Name) - alias := strings.TrimSpace(model.Alias) - if alias == "" { - alias = name - } - if alias == "" { - continue - } - key := strings.ToLower(alias) - if _, exists := seen[key]; exists { - continue - } - seen[key] = struct{}{} - display := name - if display == "" { - display = alias - } - out = append(out, &ModelInfo{ - ID: alias, - Object: "model", - Created: now, - OwnedBy: "openai", - Type: "openai", - DisplayName: display, - }) - } - return out -}