diff --git a/src/renderer/settings/components/ProviderModelList.vue b/src/renderer/settings/components/ProviderModelList.vue
index 431005094..fe03599e5 100644
--- a/src/renderer/settings/components/ProviderModelList.vue
+++ b/src/renderer/settings/components/ProviderModelList.vue
@@ -227,8 +227,9 @@
-
+
{
const statusSortWeight = (model: RENDERER_MODEL_META) => (model.enabled ? 0 : 1)
+const getModelKey = (model: RENDERER_MODEL_META) => `${model.providerId}:${model.id}`
+const statusSortOrder = ref>({})
+
+const buildStatusSortOrder = () => {
+ const models = [
+ ...props.customModels,
+ ...props.providerModels.flatMap((provider) => provider.models)
+ ]
+ const nextOrder: Record = {}
+ const orderedModels = [...models].sort((left, right) => {
+ const statusDifference = statusSortWeight(left) - statusSortWeight(right)
+ if (statusDifference !== 0) {
+ return statusDifference
+ }
+
+ return modelNameCollator.compare(left.name, right.name)
+ })
+
+ orderedModels.forEach((model, index) => {
+ nextOrder[getModelKey(model)] = index
+ })
+
+ statusSortOrder.value = nextOrder
+}
+
+const modelStructureSignature = computed(() =>
+ JSON.stringify({
+ customModels: props.customModels.map((model) => ({
+ providerId: model.providerId,
+ id: model.id,
+ name: model.name,
+ group: model.group,
+ type: model.type ?? ModelType.Chat,
+ capabilities: getModelCapabilityValues(model)
+ })),
+ providerModels: props.providerModels.map((provider) => ({
+ providerId: provider.providerId,
+ models: provider.models.map((model) => ({
+ id: model.id,
+ name: model.name,
+ group: model.group,
+ type: model.type ?? ModelType.Chat,
+ capabilities: getModelCapabilityValues(model)
+ }))
+ }))
+ })
+)
+
+watch(modelStructureSignature, buildStatusSortOrder, { immediate: true })
+
const sortModels = (models: RENDERER_MODEL_META[]) =>
[...models].sort((left, right) => {
if (filterState.sort === 'name') {
return modelNameCollator.compare(left.name, right.name)
}
- const statusDifference = statusSortWeight(left) - statusSortWeight(right)
- if (statusDifference !== 0) {
- return statusDifference
+ const leftRank = statusSortOrder.value[getModelKey(left)]
+ const rightRank = statusSortOrder.value[getModelKey(right)]
+
+ if (leftRank !== undefined || rightRank !== undefined) {
+ if (leftRank === undefined) {
+ return 1
+ }
+
+ if (rightRank === undefined) {
+ return -1
+ }
+
+ if (leftRank !== rightRank) {
+ return leftRank - rightRank
+ }
}
return modelNameCollator.compare(left.name, right.name)
@@ -634,6 +697,9 @@ const removeFilterToken = (token: FilterToken) => {
}
const setSort = (sort: ModelSortKey) => {
+ if (sort === 'status') {
+ buildStatusSortOrder()
+ }
filterState.sort = sort
sortPopoverOpen.value = false
}
diff --git a/src/renderer/src/components/settings/ModelConfigItem.vue b/src/renderer/src/components/settings/ModelConfigItem.vue
index 5f2a87d6b..f3a370183 100644
--- a/src/renderer/src/components/settings/ModelConfigItem.vue
+++ b/src/renderer/src/components/settings/ModelConfigItem.vue
@@ -35,6 +35,7 @@