Spaces:
Sleeping
Sleeping
Upload 22 files
Browse files
app.py
CHANGED
|
@@ -2814,6 +2814,65 @@ def _select_grid_candidates_with_text_ai(
|
|
| 2814 |
return candidates[:limit]
|
| 2815 |
|
| 2816 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2817 |
def _resolve_outfit_grid_sources(
|
| 2818 |
wardrobe_items: list[dict[str, Any]],
|
| 2819 |
occasion: str,
|
|
@@ -2821,6 +2880,9 @@ def _resolve_outfit_grid_sources(
|
|
| 2821 |
bottom_selected: dict[str, Any] | None,
|
| 2822 |
other_selected: dict[str, Any] | None,
|
| 2823 |
) -> tuple[list[dict[str, Any]], list[dict[str, Any]], list[dict[str, Any]], str, dict[str, Any] | None]:
|
|
|
|
|
|
|
|
|
|
| 2824 |
all_tops = [i for i in wardrobe_items if i.get("type") == "topwear"]
|
| 2825 |
all_bottoms = [i for i in wardrobe_items if i.get("type") == "bottomwear"]
|
| 2826 |
all_others = [
|
|
|
|
| 2814 |
return candidates[:limit]
|
| 2815 |
|
| 2816 |
|
| 2817 |
+
def _filter_garments_for_wedding(items: list[dict[str, Any]]) -> list[dict[str, Any]]:
|
| 2818 |
+
"""Use a single LLM call to select only wedding-appropriate garments
|
| 2819 |
+
(ethnic wear, blazers, sherwanis, formal suits, sarees, lehengas, etc.)
|
| 2820 |
+
from the full wardrobe using metadata only — no images sent."""
|
| 2821 |
+
|
| 2822 |
+
if not items:
|
| 2823 |
+
return items
|
| 2824 |
+
|
| 2825 |
+
garment_summaries = []
|
| 2826 |
+
for item in items:
|
| 2827 |
+
garment_summaries.append({
|
| 2828 |
+
"id": str(item.get("id") or ""),
|
| 2829 |
+
"type": str(item.get("type") or ""),
|
| 2830 |
+
"category": str(item.get("category") or "Unknown"),
|
| 2831 |
+
"color": str(item.get("color") or "Unknown"),
|
| 2832 |
+
"pattern": str(item.get("pattern") or "Unknown"),
|
| 2833 |
+
"fabric": str(item.get("fabric") or "Unknown"),
|
| 2834 |
+
"fit": str(item.get("fit") or "Unknown"),
|
| 2835 |
+
"style": str(item.get("style") or "Unknown"),
|
| 2836 |
+
"occasion": str(item.get("occasion") or "Unknown"),
|
| 2837 |
+
})
|
| 2838 |
+
|
| 2839 |
+
prompt = (
|
| 2840 |
+
"You are a fashion expert selecting garments suitable for a WEDDING occasion.\n\n"
|
| 2841 |
+
"Wedding-appropriate garments include:\n"
|
| 2842 |
+
"- Ethnic wear: kurtas, sherwanis, nehru jackets, sarees, lehengas, churidars, dhotis, salwar kameez\n"
|
| 2843 |
+
"- Formal/semi-formal: blazers, suit jackets, dress shirts, formal trousers, dress pants, waistcoats\n"
|
| 2844 |
+
"- Elegant pieces: silk fabrics, embroidered items, brocade, velvet\n"
|
| 2845 |
+
"- Accessories that work for weddings: formal shoes, stoles, dupattas\n\n"
|
| 2846 |
+
"Garments to EXCLUDE:\n"
|
| 2847 |
+
"- Casual everyday items: plain t-shirts, basic tees, hoodies, sweatshirts, joggers, denim jeans, gym shorts\n"
|
| 2848 |
+
"- Sportswear, athleisure, distressed or ripped clothing\n"
|
| 2849 |
+
"- Very casual items like graphic tees, cargo shorts, flip-flops\n\n"
|
| 2850 |
+
"If a garment is borderline (e.g. a smart chino, a dark polo), include it only if it could realistically "
|
| 2851 |
+
"be part of a wedding guest outfit.\n\n"
|
| 2852 |
+
"From the garments below, return ONLY the IDs of those appropriate for a wedding.\n"
|
| 2853 |
+
"Return strictly valid JSON and nothing else.\n\n"
|
| 2854 |
+
"Return EXACT shape:\n"
|
| 2855 |
+
"{\"selected_ids\":[\"id1\",\"id2\",...]}\n\n"
|
| 2856 |
+
f"Garments JSON:\n{json.dumps(garment_summaries, ensure_ascii=True)}"
|
| 2857 |
+
)
|
| 2858 |
+
|
| 2859 |
+
try:
|
| 2860 |
+
response_text = run_nvidia_text_inference(prompt, max_tokens=OUTFIT_TEXT_SELECTOR_MAX_TOKENS)
|
| 2861 |
+
parsed = parse_json_from_text(response_text)
|
| 2862 |
+
selected_ids_raw = parsed.get("selected_ids") if isinstance(parsed, dict) else None
|
| 2863 |
+
if not isinstance(selected_ids_raw, list):
|
| 2864 |
+
print("[wedding-filter] LLM returned no selected_ids, using all items")
|
| 2865 |
+
return items
|
| 2866 |
+
|
| 2867 |
+
selected_ids = {str(v).strip() for v in selected_ids_raw if str(v).strip()}
|
| 2868 |
+
filtered = [i for i in items if str(i.get("id") or "").strip() in selected_ids]
|
| 2869 |
+
print(f"[wedding-filter] in={len(items)} kept={len(filtered)} ids={selected_ids}")
|
| 2870 |
+
return filtered if filtered else items
|
| 2871 |
+
except Exception as exc:
|
| 2872 |
+
print(f"[wedding-filter] LLM call failed reason={exc!r}, using all items")
|
| 2873 |
+
return items
|
| 2874 |
+
|
| 2875 |
+
|
| 2876 |
def _resolve_outfit_grid_sources(
|
| 2877 |
wardrobe_items: list[dict[str, Any]],
|
| 2878 |
occasion: str,
|
|
|
|
| 2880 |
bottom_selected: dict[str, Any] | None,
|
| 2881 |
other_selected: dict[str, Any] | None,
|
| 2882 |
) -> tuple[list[dict[str, Any]], list[dict[str, Any]], list[dict[str, Any]], str, dict[str, Any] | None]:
|
| 2883 |
+
if occasion == "wedding":
|
| 2884 |
+
wardrobe_items = _filter_garments_for_wedding(wardrobe_items)
|
| 2885 |
+
|
| 2886 |
all_tops = [i for i in wardrobe_items if i.get("type") == "topwear"]
|
| 2887 |
all_bottoms = [i for i in wardrobe_items if i.get("type") == "bottomwear"]
|
| 2888 |
all_others = [
|