Commit 0d5ca6009 for llama.cpp
commit 0d5ca600984b09f5d12886c720216bbc84f9929d
Author: Aleksander Grygier <aleksander.grygier@gmail.com>
Date: Tue Oct 27 06:52:54 2026 +0100
ui: list org-less models first in the model selector (#31215)
The org-less group renders without a header, so when it followed a named
org its models looked like they belonged to that org. Put it ahead of the
named org groups.
Fixes #25227
Assisted-by: Claude (Opus 5.5 Medium)
diff --git a/tools/ui/src/lib/utils/model-list.ts b/tools/ui/src/lib/utils/model-list.ts
index ba3c67ae6..632836f16 100644
--- a/tools/ui/src/lib/utils/model-list.ts
+++ b/tools/ui/src/lib/utils/model-list.ts
@@ -100,7 +100,9 @@ export function groupModelOptions(filteredOptions: ModelOption[]): GroupedModelO
}
for (const [orgName, items] of orgGroups) {
- available.push({ items, orgName: orgName || null });
+ // The org-less group has no header, so it goes first to not read as part of the org above it
+ if (orgName) available.push({ items, orgName });
+ else available.unshift({ items, orgName: null });
}
return { available };
diff --git a/tools/ui/tests/unit/model-list.test.ts b/tools/ui/tests/unit/model-list.test.ts
index 3037cdaa1..5b135dcd2 100644
--- a/tools/ui/tests/unit/model-list.test.ts
+++ b/tools/ui/tests/unit/model-list.test.ts
@@ -90,7 +90,7 @@ describe('filterModelOptions', () => {
});
describe('groupModelOptions', () => {
- it('groups the options by org, unnamed last', () => {
+ it('groups the options by org, unnamed first', () => {
const grouped = groupModelOptions([
option('org/a', 'org'),
option('org/b', 'org'),
@@ -98,7 +98,21 @@ describe('groupModelOptions', () => {
option('plain')
]);
- expect(grouped.available.map((group) => group.orgName)).toEqual(['org', 'other', null]);
- expect(grouped.available[0].items.map((item) => item.option.model)).toEqual(['org/a', 'org/b']);
+ expect(grouped.available.map((group) => group.orgName)).toEqual([null, 'org', 'other']);
+ expect(grouped.available[1].items.map((item) => item.option.model)).toEqual(['org/a', 'org/b']);
+ });
+
+ it('keeps org-less options together ahead of the org they follow', () => {
+ const grouped = groupModelOptions([
+ option('Qwen/Qwen2.5', 'Qwen'),
+ option('gemma-3'),
+ option('gpt-oss'),
+ option('unsloth/Qwen3.6', 'unsloth'),
+ option('qwen3.6')
+ ]);
+
+ expect(grouped.available.map((group) => group.orgName)).toEqual([null, 'Qwen', 'unsloth']);
+ expect(grouped.available[0].items.map((item) => item.option.model)) //
+ .toEqual(['gemma-3', 'gpt-oss', 'qwen3.6']);
});
});