Four coupled operator-asked changes to the view modal (Scribe plan #509): 1. **Autofocus tag entry on modal open** — TagAutocomplete grabs focus in onMounted/nextTick so the caret is in the input the moment the modal renders. No click needed to start typing. 2. **General suggestions expanded by default** — SuggestionsPanel's general-category group now mounts with `:default-open="true"`. Operator can collapse if too noisy, but the v1 frame shows them. 3. **Lower general threshold default 0.95 → 0.50** — MLSettings. suggestion_threshold_general default matches character. Alembic 0029 also bumps the existing singleton row's value if it's still at the old 0.95. Operator can re-tune from Settings → ML. 4. **Retire `copyright` + `artist` as ML suggestion categories** — neither feeds a Tag.kind (`artist` retired in FC-2d-vii-c, never really existed as a copyright tag-kind). They were surfaced in the suggestions pipeline + threshold settings UI but had no follow- through. Drop from SURFACED_CATEGORIES, suggestions._threshold_for, ml_admin GET/PATCH allowlist, MLSettings columns (alembic 0029 drops the two columns), frontend CATEGORY_ORDER + CATEGORY_LABELS, SuggestionsPanel.peopleCats, AliasPickerDialog kind-check, and MLThresholdSliders rows. Out of scope (intentional): `tag_kind` Postgres enum still includes `artist` for historic Tag row queryability (per the model comment); no operator pain reported, no enum-shrink needed. Tests: - test_surfaced_categories asserts {character, general}, excludes artist + copyright. - test_threshold_for_artist_is_unsurfaced extended to cover copyright. - test_get_and_patch_settings asserts new 0.50 default and the absent artist + copyright keys in the GET payload.
42 lines
1.3 KiB
Vue
42 lines
1.3 KiB
Vue
<template>
|
|
<v-card>
|
|
<v-card-title>Suggestion thresholds</v-card-title>
|
|
<v-card-text v-if="store.settings">
|
|
<v-row v-for="f in fields" :key="f.key">
|
|
<v-col cols="12">
|
|
<v-slider
|
|
v-model="local[f.key]" :label="f.label"
|
|
min="0" max="1" step="0.05" thumb-label hide-details
|
|
color="accent" @end="save"
|
|
/>
|
|
</v-col>
|
|
</v-row>
|
|
</v-card-text>
|
|
<v-card-text v-else><v-skeleton-loader type="paragraph" /></v-card-text>
|
|
</v-card>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { toast } from '../../utils/toast.js'
|
|
import { reactive, watch } from 'vue'
|
|
import { useMLStore } from '../../stores/ml.js'
|
|
|
|
const store = useMLStore()
|
|
// 'artist' (FC-2d-vii-c) and 'copyright' (2026-06-01) retired as
|
|
// suggestion categories; their threshold rows are gone.
|
|
const fields = [
|
|
{ key: 'suggestion_threshold_character', label: 'Character' },
|
|
{ key: 'suggestion_threshold_general', label: 'General' },
|
|
{ key: 'centroid_similarity_threshold', label: 'Centroid similarity' }
|
|
]
|
|
const local = reactive({})
|
|
watch(() => store.settings, (s) => { if (s) Object.assign(local, s) }, { immediate: true })
|
|
|
|
async function save() {
|
|
const patch = {}
|
|
for (const f of fields) patch[f.key] = local[f.key]
|
|
try { await store.patchSettings(patch) }
|
|
catch (e) { toast({ text: e.message, type: 'error' }) }
|
|
}
|
|
</script>
|