-
-
Notifications
You must be signed in to change notification settings - Fork 6.5k
fix(cliproxy): keep original model ids routable with aliases #4125
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: dev
Are you sure you want to change the base?
Changes from 1 commit
8b42bc3
adc389d
28f8f0a
a2a2cb2
e9df43e
cc21639
5afc7ef
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2479,12 +2479,15 @@ func buildOpenAICompatibilityConfigModels(compat *config.OpenAICompatibility) [] | |
| return nil | ||
| } | ||
| now := time.Now().Unix() | ||
| models := make([]*ModelInfo, 0, len(compat.Models)) | ||
| models := make([]*ModelInfo, 0, len(compat.Models)*2) | ||
| seen := make(map[string]struct{}, len(compat.Models)*2) | ||
| for i := range compat.Models { | ||
| model := compat.Models[i] | ||
| modelID := strings.TrimSpace(model.Alias) | ||
| alias := strings.TrimSpace(model.Alias) | ||
| name := strings.TrimSpace(model.Name) | ||
| modelID := alias | ||
| if modelID == "" { | ||
| modelID = strings.TrimSpace(model.Name) | ||
| modelID = name | ||
| } | ||
| if modelID == "" { | ||
| continue | ||
|
|
@@ -2497,7 +2500,7 @@ func buildOpenAICompatibilityConfigModels(compat *config.OpenAICompatibility) [] | |
| if thinking == nil && !model.Image { | ||
| thinking = ®istry.ThinkingSupport{Levels: []string{"low", "medium", "high"}} | ||
| } | ||
| models = append(models, &ModelInfo{ | ||
| info := &ModelInfo{ | ||
| ID: modelID, | ||
| Object: "model", | ||
| Created: now, | ||
|
|
@@ -2506,18 +2509,49 @@ func buildOpenAICompatibilityConfigModels(compat *config.OpenAICompatibility) [] | |
| DisplayName: modelID, | ||
| UserDefined: false, | ||
| Thinking: thinking, | ||
| }) | ||
| } | ||
| models = appendModelInfoIfUnique(models, info, seen) | ||
| if alias != "" && name != "" && !strings.EqualFold(alias, name) { | ||
| models = appendModelInfoIfUnique(models, &ModelInfo{ | ||
| ID: name, | ||
| Object: "model", | ||
| Created: now, | ||
| OwnedBy: compat.Name, | ||
| Type: modelType, | ||
| DisplayName: name, | ||
| UserDefined: false, | ||
| Thinking: thinking, | ||
| }, seen) | ||
| } | ||
| } | ||
| return models | ||
| } | ||
|
|
||
| func appendModelInfoIfUnique(models []*ModelInfo, info *ModelInfo, seen map[string]struct{}) []*ModelInfo { | ||
| if info == nil { | ||
| return models | ||
| } | ||
| modelID := strings.TrimSpace(info.ID) | ||
| if modelID == "" { | ||
| return models | ||
| } | ||
| key := strings.ToLower(modelID) | ||
| if _, exists := seen[key]; exists { | ||
| return models | ||
| } | ||
| seen[key] = struct{}{} | ||
| clone := *info | ||
| clone.ID = modelID | ||
| return append(models, &clone) | ||
|
daiaji marked this conversation as resolved.
Outdated
|
||
| } | ||
|
|
||
| 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(models)) | ||
| seen := make(map[string]struct{}, len(models)) | ||
| out := make([]*ModelInfo, 0, len(models)*2) | ||
| seen := make(map[string]struct{}, len(models)*2) | ||
| for i := range models { | ||
| model := models[i] | ||
| name := strings.TrimSpace(model.GetName()) | ||
|
|
@@ -2528,11 +2562,6 @@ func buildConfigModels[T modelEntry](models []T, ownedBy, modelType string) []*M | |
| if alias == "" { | ||
| continue | ||
| } | ||
| key := strings.ToLower(alias) | ||
| if _, exists := seen[key]; exists { | ||
| continue | ||
| } | ||
| seen[key] = struct{}{} | ||
| display := name | ||
| if display == "" { | ||
| display = alias | ||
|
|
@@ -2551,7 +2580,22 @@ func buildConfigModels[T modelEntry](models []T, ownedBy, modelType string) []*M | |
| info.Thinking = upstream.Thinking | ||
| } | ||
| } | ||
| out = append(out, info) | ||
| out = appendModelInfoIfUnique(out, info, seen) | ||
| if name != "" && !strings.EqualFold(alias, name) { | ||
| nameInfo := &ModelInfo{ | ||
| ID: name, | ||
| Object: "model", | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
When one API-key config aliases a built-in model while another credential for the same provider registers the normal catalog, this new original-ID entry can be the last Useful? React with 👍 / 👎. |
||
| Created: now, | ||
| OwnedBy: ownedBy, | ||
| Type: modelType, | ||
| DisplayName: name, | ||
| UserDefined: true, | ||
| } | ||
| if upstream := registry.LookupStaticModelInfo(name); upstream != nil && upstream.Thinking != nil { | ||
| nameInfo.Thinking = upstream.Thinking | ||
| } | ||
| out = appendModelInfoIfUnique(out, nameInfo, seen) | ||
| } | ||
| } | ||
| return out | ||
| } | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When a configured alias differs from the upstream name only by capitalization, this case-folded de-dupe (together with the
EqualFoldchecks in the two builders) still registers only the alias. Provider lookup is an exact map lookup by the requested model ID, soName: "gpt-5"withAlias: "GPT-5"leaves requests for the real upstreamgpt-5failing withunknown provider for model, even though this change is intended to keep original IDs routable.Useful? React with 👍 / 👎.