fix(suggestions): pill × removal also suppresses re-auto-accept
The previous fix only covered the suggestion-chip ✕ flow (which calls /suggestions/reject). Removing a tag via the pill × in the Tags section goes through /tags/remove and wrote no feedback row, so the per-image rejection filter in get_suggestions had nothing to match on — auto-accept would re-apply the tag on the next modal load. /tags/remove now writes SuggestionFeedback(decision='rejected', suggestion_source='manual_removal', confidence=0) alongside the image_tags delete. The suggestion_source value distinguishes these rows from chip-reject rejections in the feedback log without complicating the get_suggestions filter (it matches on decision alone). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
+16
-2
@@ -1211,14 +1211,28 @@ def add_tag(image_id):
|
||||
|
||||
@main.post("/image/<int:image_id>/tags/remove")
|
||||
def remove_tag(image_id):
|
||||
"""Remove a tag from an image.
|
||||
|
||||
Also logs a SuggestionFeedback rejection so the auto-suggest + auto-accept
|
||||
systems treat this as 'the user said no to this tag for this image'.
|
||||
Without the rejection row, a removed tag whose WD14 prediction still sits
|
||||
at/above the auto-accept threshold would re-apply itself on the next
|
||||
modal load.
|
||||
"""
|
||||
Minimal JSON endpoint to remove a tag from an image.
|
||||
"""
|
||||
from app.models import SuggestionFeedback
|
||||
|
||||
name = (request.form.get("name") or "").strip()
|
||||
img = ImageRecord.query.get_or_404(image_id)
|
||||
tag = Tag.query.filter_by(name=name).first()
|
||||
if tag and tag in img.tags:
|
||||
img.tags.remove(tag)
|
||||
db.session.add(SuggestionFeedback(
|
||||
image_id=image_id,
|
||||
tag_name=name,
|
||||
suggestion_source='manual_removal',
|
||||
confidence=0.0,
|
||||
decision='rejected',
|
||||
))
|
||||
db.session.commit()
|
||||
return jsonify(ok=True)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user