Skip to content

Commit e76e04f

Browse files
ganisbackcsglite
andcommitted
feat: prioritize local models in model list
Local models (source=local or format=gguf/safetensors) now appear first in the model list, making them easier to find and select. Generated with AI Co-Authored-By: csglite <xzhgan@gmail.com>
1 parent 4c49791 commit e76e04f

2 files changed

Lines changed: 39 additions & 0 deletions

File tree

internal/server/cloud_models.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,12 @@ func (s *Server) refreshCloudChatModels(ctx context.Context) ([]api.ModelInfo, e
130130

131131
func sortModelsByPriority(models []api.ModelInfo) {
132132
sort.SliceStable(models, func(i, j int) bool {
133+
iIsLocal := isLocalModelInfo(models[i])
134+
jIsLocal := isLocalModelInfo(models[j])
135+
if iIsLocal != jIsLocal {
136+
return iIsLocal
137+
}
138+
133139
iType := strings.TrimSpace(strings.ToLower(models[i].LLMType))
134140
jType := strings.TrimSpace(strings.ToLower(models[j].LLMType))
135141
iOwner := strings.TrimSpace(strings.ToLower(models[i].OwnedBy))
@@ -150,3 +156,9 @@ func sortModelsByPriority(models []api.ModelInfo) {
150156
return models[i].Model < models[j].Model
151157
})
152158
}
159+
160+
func isLocalModelInfo(model api.ModelInfo) bool {
161+
source := strings.TrimSpace(strings.ToLower(model.Source))
162+
format := strings.TrimSpace(strings.ToLower(model.Format))
163+
return source == "local" || format == "gguf" || format == "safetensors"
164+
}

internal/server/cloud_models_test.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,33 @@ func TestHandleCloudAuthTokenSaveInvalidatesCloudModelCache(t *testing.T) {
213213
}
214214
}
215215

216+
func TestSortModelsByPriorityKeepsLocalModelsFirst(t *testing.T) {
217+
models := []api.ModelInfo{
218+
{Model: "z/cloud-external", Source: "cloud", Format: "cloud", LLMType: "external_llm"},
219+
{Model: "z/local", Source: "local", Format: "gguf"},
220+
{Model: "a/cloud-opencsg", Source: "cloud", Format: "cloud", OwnedBy: "opencsg"},
221+
{Model: "a/local-safetensors", Format: "safetensors"},
222+
{Model: "b/cloud-other", Source: "cloud", Format: "cloud"},
223+
}
224+
225+
sortModelsByPriority(models)
226+
227+
got := make([]string, 0, len(models))
228+
for _, model := range models {
229+
got = append(got, model.Model)
230+
}
231+
want := []string{
232+
"a/local-safetensors",
233+
"z/local",
234+
"z/cloud-external",
235+
"a/cloud-opencsg",
236+
"b/cloud-other",
237+
}
238+
if strings.Join(got, ",") != strings.Join(want, ",") {
239+
t.Fatalf("sorted models = %#v, want %#v", got, want)
240+
}
241+
}
242+
216243
func containsModelID(modelIDs []string, want string) bool {
217244
for _, item := range modelIDs {
218245
if item == want {

0 commit comments

Comments
 (0)