Reference in New Issue
Block a user
Delete Branch "dev"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Hovering a tag highlights the exact crop region on the image that explains it — visual proof the crop→SigLIP bag is firing. Hover a concept → its crop lights up (a proposer region won); the whole-image frame → the global vector won (not localized).
Steps
score_image(heads.py) keeps the ARGMAX beside the max-over-bag → each surfaced tag carriesgrounding {bbox, kind, detector}(or null when the whole-image vector won). Threaded through SuggestionService +/suggestionspayload.ImageCanvasoverlay tracks the rendered image rect (correct under object-fit + pan/zoom) and draws the region; suggestion rows hover→overlay via afcSuggestionHoverprovide/inject, in both the modal and Explore. Null grounding → a subtle whole-image frame.GET /api/images/<id>/tags/<id>/groundingruns the applied tag's head over the same bag (argmax) →{grounding, has_head}; chips reuse the Step-3 overlay.has_head=false(nothing to localize with) → no overlay.No migration — this is a read-path + UI change. CI green on dev head
2638cf1(run 1962): ruff, frontend build (npm test:unit + build), backend unit, and integration all pass.🤖 Generated with Claude Code
score_image now keeps the ARGMAX beside the max-over-bag: which bag row won each head. The region query also selects bbox/kind/detector_version, a parallel bag_meta maps each row → its region (None for the whole-image vector), and every hit gains grounding {bbox,kind,detector} (null when the global vector won). Threaded through SuggestionService (new Suggestion.grounding field) → /api/.../suggestions payload. This is the data the #1206 hover-overlay draws. CCIP-only hits ground null for now (figure grounding = step 2). Tests: winning crop grounds the tag with its bbox+kind; whole-image win → grounding None. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CDgx8bQS5YrGRK76v8HUnMmatch_image now tracks WHICH query figure produced the winning cosine per character (argmax over the per-figure best-reference sim) and attaches its bbox as grounding {bbox,kind:'figure',detector}. SuggestionService carries it: a CCIP-only character hit grounds to its figure; a 'both' hit keeps the head's localized crop if it had one, else falls back to the CCIP figure — so corroborated characters stay grounded. Test: a character match carries the matched figure's bbox+kind. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CDgx8bQS5YrGRK76v8HUnMThe payoff: hover a suggestion in the rail and the exact crop that produced it lights up on the image (a booru:head, a panel, a figure); a null-grounding tag shows a subtle dashed whole-image frame ('global vector won, not a crop'). ImageCanvas gains a grounding overlay that tracks the <img>'s live bounding rect (correct under object-fit letterboxing + pan/zoom) and draws the normalized bbox + a detector/kind label. SuggestionItem sets the hovered grounding via provide/inject (no 4-level event relay through TagPanel/SuggestionsPanel/group); ImageViewer AND ExploreView provide it + pass it to their canvas. Overlay is pointer-events:none so it never blocks pan/zoom/click. Videos out of v1 scope. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CDgx8bQS5YrGRK76v8HUnMApplied tags aren't scored live, so compute the grounding on demand: run the tag's head over the image's max-over-bag (whole-image + concept crops), argmax → the region that best explains the tag on this image, mirroring what score_image records for live suggestions. - heads.py: extract _image_bag (now shared by score_image) + ground_applied_tag. Returns (grounding, has_head): has_head False = no head to localize with → no overlay; grounding None = the whole-image vector won → whole-image frame. - tags.py: GET /api/images/<id>/tags/<id>/grounding → {grounding, has_head}. - TagChip/TagPanel: applied chips inject fcSuggestionHover and fetch grounding on hover (cached per image+tag, race-guarded), reusing Step 3's overlay in both the modal and Explore. No new frontend overlay code. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CDgx8bQS5YrGRK76v8HUnM