Food Desert commited on
Commit
173ca53
·
1 Parent(s): 0cd97fa

Preserve user toggled provenance across Rebuild Rows

Browse files
Files changed (2) hide show
  1. app.py +19 -4
  2. scripts/smoke_ui_state.py +37 -0
app.py CHANGED
@@ -555,6 +555,14 @@ def _build_toggle_rows(
555
  )
556
  )
557
  selected_index: Dict[str, int] = {t: i for i, t in enumerate(selected_active)}
 
 
 
 
 
 
 
 
558
 
559
  row_defs: List[Dict[str, Any]] = []
560
  enabled_group_tag_sets: Dict[str, Set[str]] = {
@@ -605,7 +613,7 @@ def _build_toggle_rows(
605
  retrieved_other_meta = {
606
  t: {
607
  "origin": _normalize_selection_origin(tag_selection_origins.get(t, "selection")),
608
- "preselected": t in selected_active,
609
  }
610
  for t in merged_retrieved_other
611
  }
@@ -632,7 +640,7 @@ def _build_toggle_rows(
632
  selected_other_meta = {
633
  t: {
634
  "origin": _normalize_selection_origin(tag_selection_origins.get(t, "selection")),
635
- "preselected": True,
636
  }
637
  for t in selected_other
638
  }
@@ -668,7 +676,7 @@ def _build_toggle_rows(
668
  tag_meta = {
669
  t: {
670
  "origin": _normalize_selection_origin(tag_selection_origins.get(t, "selection")),
671
- "preselected": t in selected_active,
672
  }
673
  for t in merged
674
  }
@@ -1010,6 +1018,7 @@ def _rebuild_rows_from_selected(
1010
  if t and not _is_artist_tag(t) and not _is_excluded_recommendation_tag(t)
1011
  )
1012
  )
 
1013
 
1014
  retrieved_candidate_tags: List[str] = []
1015
  tag_selection_origins: Dict[str, str] = {}
@@ -1025,7 +1034,13 @@ def _rebuild_rows_from_selected(
1025
  retrieved_candidate_tags.append(tn)
1026
  if tn not in tag_selection_origins:
1027
  meta = row_meta.get(t, {}) if isinstance(row_meta.get(t, {}), dict) else {}
1028
- tag_selection_origins[tn] = _normalize_selection_origin(str(meta.get("origin", "selection")))
 
 
 
 
 
 
1029
 
1030
  for t in selected_active:
1031
  tag_selection_origins.setdefault(t, "user")
 
555
  )
556
  )
557
  selected_index: Dict[str, int] = {t: i for i, t in enumerate(selected_active)}
558
+ selected_set: Set[str] = set(selected_active)
559
+
560
+ def _is_pipeline_preselected(tag: str) -> bool:
561
+ # Tags explicitly user-toggled should keep user coloring after row rebuilds.
562
+ # Only non-user selected tags should render as pipeline-preselected.
563
+ if tag not in selected_set:
564
+ return False
565
+ return _normalize_selection_origin(tag_selection_origins.get(tag, "selection")) != "user"
566
 
567
  row_defs: List[Dict[str, Any]] = []
568
  enabled_group_tag_sets: Dict[str, Set[str]] = {
 
613
  retrieved_other_meta = {
614
  t: {
615
  "origin": _normalize_selection_origin(tag_selection_origins.get(t, "selection")),
616
+ "preselected": _is_pipeline_preselected(t),
617
  }
618
  for t in merged_retrieved_other
619
  }
 
640
  selected_other_meta = {
641
  t: {
642
  "origin": _normalize_selection_origin(tag_selection_origins.get(t, "selection")),
643
+ "preselected": _is_pipeline_preselected(t),
644
  }
645
  for t in selected_other
646
  }
 
676
  tag_meta = {
677
  t: {
678
  "origin": _normalize_selection_origin(tag_selection_origins.get(t, "selection")),
679
+ "preselected": _is_pipeline_preselected(t),
680
  }
681
  for t in merged
682
  }
 
1018
  if t and not _is_artist_tag(t) and not _is_excluded_recommendation_tag(t)
1019
  )
1020
  )
1021
+ selected_active_set: Set[str] = set(selected_active)
1022
 
1023
  retrieved_candidate_tags: List[str] = []
1024
  tag_selection_origins: Dict[str, str] = {}
 
1034
  retrieved_candidate_tags.append(tn)
1035
  if tn not in tag_selection_origins:
1036
  meta = row_meta.get(t, {}) if isinstance(row_meta.get(t, {}), dict) else {}
1037
+ meta_origin = _normalize_selection_origin(str(meta.get("origin", "selection")))
1038
+ meta_preselected = bool(meta.get("preselected", False))
1039
+ # Preserve explicit user toggles across rebuild:
1040
+ # if a currently selected tag was not pipeline-preselected, keep user provenance.
1041
+ if tn in selected_active_set and not meta_preselected:
1042
+ meta_origin = "user"
1043
+ tag_selection_origins[tn] = meta_origin
1044
 
1045
  for t in selected_active:
1046
  tag_selection_origins.setdefault(t, "user")
scripts/smoke_ui_state.py CHANGED
@@ -189,6 +189,42 @@ def test_toggle_then_rebuild_does_not_resurrect_removed_tag() -> None:
189
  _assert("cub" in prompt_after_rebuild, "other retrieved selection should remain")
190
 
191
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
192
  def test_toggle_does_not_cross_activate_unrelated_row_tag() -> None:
193
  row_defs = [
194
  {"name": "organization", "label": "Organization", "tags": ["pinup", "close-up"], "tag_meta": {}},
@@ -268,6 +304,7 @@ def main() -> None:
268
  test_row_deduping()
269
  test_rebuild_ignores_stale_selected_state()
270
  test_toggle_then_rebuild_does_not_resurrect_removed_tag()
 
271
  test_toggle_does_not_cross_activate_unrelated_row_tag()
272
  test_shared_tag_mirrors_without_unrelated_cross_toggle()
273
  print("ui state smoke: ok")
 
189
  _assert("cub" in prompt_after_rebuild, "other retrieved selection should remain")
190
 
191
 
192
+ def test_rebuild_preserves_user_toggled_provenance() -> None:
193
+ row_defs = [
194
+ {
195
+ "name": "demo_row",
196
+ "label": "Demo Row",
197
+ "tags": ["base_tag", "manual_tag"],
198
+ "tag_meta": {
199
+ "base_tag": {"origin": "selection", "preselected": True},
200
+ "manual_tag": {"origin": "selection", "preselected": False},
201
+ },
202
+ }
203
+ ]
204
+ selected_state = ["base_tag", "manual_tag"]
205
+ row_values_state = [["base_tag", "manual_tag"]]
206
+ out = app._rebuild_rows_from_selected(
207
+ selected_state,
208
+ row_defs,
209
+ row_values_state,
210
+ app.display_top_groups_default,
211
+ app.display_top_tags_per_group_default,
212
+ app.display_rank_top_k_default,
213
+ )
214
+ rebuilt_rows = out[6]
215
+ manual_meta = None
216
+ for row in rebuilt_rows:
217
+ tags = row.get("tags", []) if isinstance(row, dict) else []
218
+ if "manual_tag" in tags:
219
+ row_meta = row.get("tag_meta", {}) if isinstance(row.get("tag_meta", {}), dict) else {}
220
+ manual_meta = row_meta.get("manual_tag")
221
+ if manual_meta:
222
+ break
223
+ _assert(manual_meta is not None, "manual_tag metadata missing after rebuild")
224
+ _assert(manual_meta.get("origin") == "user", "rebuild should preserve manual_tag origin as user")
225
+ _assert(manual_meta.get("preselected") is False, "rebuild should preserve manual_tag preselected=False")
226
+
227
+
228
  def test_toggle_does_not_cross_activate_unrelated_row_tag() -> None:
229
  row_defs = [
230
  {"name": "organization", "label": "Organization", "tags": ["pinup", "close-up"], "tag_meta": {}},
 
304
  test_row_deduping()
305
  test_rebuild_ignores_stale_selected_state()
306
  test_toggle_then_rebuild_does_not_resurrect_removed_tag()
307
+ test_rebuild_preserves_user_toggled_provenance()
308
  test_toggle_does_not_cross_activate_unrelated_row_tag()
309
  test_shared_tag_mirrors_without_unrelated_cross_toggle()
310
  print("ui state smoke: ok")