Skip to content

Commit 1a34f55

Browse files
authored
fix(settings): stabilize provider model toggles (#1444)
1 parent fe3c8b1 commit 1a34f55

2 files changed

Lines changed: 71 additions & 4 deletions

File tree

src/renderer/settings/components/ProviderModelList.vue

Lines changed: 70 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -227,8 +227,9 @@
227227
</Button>
228228
</div>
229229
</div>
230-
<div v-else-if="isModelItem(item)" class="bg-card">
230+
<div v-else-if="isModelItem(item)" :key="item.id" class="bg-card">
231231
<ModelConfigItem
232+
:key="item.id"
232233
:model-name="item.model.name"
233234
:model-id="item.model.id"
234235
:provider-id="item.providerId"
@@ -458,15 +459,77 @@ const matchesAdvancedFilters = (model: RENDERER_MODEL_META) => {
458459
459460
const statusSortWeight = (model: RENDERER_MODEL_META) => (model.enabled ? 0 : 1)
460461
462+
const getModelKey = (model: RENDERER_MODEL_META) => `${model.providerId}:${model.id}`
463+
const statusSortOrder = ref<Record<string, number>>({})
464+
465+
const buildStatusSortOrder = () => {
466+
const models = [
467+
...props.customModels,
468+
...props.providerModels.flatMap((provider) => provider.models)
469+
]
470+
const nextOrder: Record<string, number> = {}
471+
const orderedModels = [...models].sort((left, right) => {
472+
const statusDifference = statusSortWeight(left) - statusSortWeight(right)
473+
if (statusDifference !== 0) {
474+
return statusDifference
475+
}
476+
477+
return modelNameCollator.compare(left.name, right.name)
478+
})
479+
480+
orderedModels.forEach((model, index) => {
481+
nextOrder[getModelKey(model)] = index
482+
})
483+
484+
statusSortOrder.value = nextOrder
485+
}
486+
487+
const modelStructureSignature = computed(() =>
488+
JSON.stringify({
489+
customModels: props.customModels.map((model) => ({
490+
providerId: model.providerId,
491+
id: model.id,
492+
name: model.name,
493+
group: model.group,
494+
type: model.type ?? ModelType.Chat,
495+
capabilities: getModelCapabilityValues(model)
496+
})),
497+
providerModels: props.providerModels.map((provider) => ({
498+
providerId: provider.providerId,
499+
models: provider.models.map((model) => ({
500+
id: model.id,
501+
name: model.name,
502+
group: model.group,
503+
type: model.type ?? ModelType.Chat,
504+
capabilities: getModelCapabilityValues(model)
505+
}))
506+
}))
507+
})
508+
)
509+
510+
watch(modelStructureSignature, buildStatusSortOrder, { immediate: true })
511+
461512
const sortModels = (models: RENDERER_MODEL_META[]) =>
462513
[...models].sort((left, right) => {
463514
if (filterState.sort === 'name') {
464515
return modelNameCollator.compare(left.name, right.name)
465516
}
466517
467-
const statusDifference = statusSortWeight(left) - statusSortWeight(right)
468-
if (statusDifference !== 0) {
469-
return statusDifference
518+
const leftRank = statusSortOrder.value[getModelKey(left)]
519+
const rightRank = statusSortOrder.value[getModelKey(right)]
520+
521+
if (leftRank !== undefined || rightRank !== undefined) {
522+
if (leftRank === undefined) {
523+
return 1
524+
}
525+
526+
if (rightRank === undefined) {
527+
return -1
528+
}
529+
530+
if (leftRank !== rightRank) {
531+
return leftRank - rightRank
532+
}
470533
}
471534
472535
return modelNameCollator.compare(left.name, right.name)
@@ -634,6 +697,9 @@ const removeFilterToken = (token: FilterToken) => {
634697
}
635698
636699
const setSort = (sort: ModelSortKey) => {
700+
if (sort === 'status') {
701+
buildStatusSortOrder()
702+
}
637703
filterState.sort = sort
638704
sortPopoverOpen.value = false
639705
}

src/renderer/src/components/settings/ModelConfigItem.vue

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
</span>
3636
<Switch
3737
v-if="!hideEnableToggle"
38+
:key="`${providerId}:${modelId}`"
3839
:model-value="enabled"
3940
@update:model-value="onEnabledChange"
4041
/>

0 commit comments

Comments
 (0)