af7b5c95e9
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.6 KiB
Python
42 lines
1.6 KiB
Python
"""MLSettings — single-row table holding ML pipeline tunables."""
|
|
|
|
from datetime import datetime
|
|
|
|
from sqlalchemy import CheckConstraint, DateTime, Float, Integer, String, func
|
|
from sqlalchemy.orm import Mapped, mapped_column
|
|
|
|
from .base import Base
|
|
|
|
|
|
class MLSettings(Base):
|
|
__tablename__ = "ml_settings"
|
|
# Bare name — Base.metadata's naming convention prepends ck_<table>_,
|
|
# producing the final ck_ml_settings_singleton (matches migration 0003).
|
|
__table_args__ = (CheckConstraint("id = 1", name="singleton"),)
|
|
|
|
id: Mapped[int] = mapped_column(Integer, primary_key=True)
|
|
suggestion_threshold_character: Mapped[float] = mapped_column(
|
|
Float, nullable=False, default=0.50
|
|
)
|
|
# Default lowered 0.95 → 0.50 on 2026-06-01 — operator-flagged that
|
|
# 0.95 hid most general suggestions. Operator-tunable via Settings →
|
|
# ML if too noisy.
|
|
suggestion_threshold_general: Mapped[float] = mapped_column(
|
|
Float, nullable=False, default=0.50
|
|
)
|
|
centroid_similarity_threshold: Mapped[float] = mapped_column(
|
|
Float, nullable=False, default=0.55
|
|
)
|
|
min_reference_images: Mapped[int] = mapped_column(
|
|
Integer, nullable=False, default=5
|
|
)
|
|
tagger_model_version: Mapped[str] = mapped_column(
|
|
String(128), nullable=False, default="camie-tagger-v2"
|
|
)
|
|
embedder_model_version: Mapped[str] = mapped_column(
|
|
String(128), nullable=False, default="siglip-so400m-patch14-384"
|
|
)
|
|
updated_at: Mapped[datetime] = mapped_column(
|
|
DateTime(timezone=True), nullable=False, server_default=func.now()
|
|
)
|