Spaces:
Runtime error
Runtime error
Commit History
-
fix (llm): improve prompts for choosing outfits
d81d91f -
feat(combinations): improve Get Dressed LLM ranking prompt
- Always rank combinations with the LLM, even without occasion text (previously only cartesian product order was shown). - Add stylist system prompt with explicit criteria: occasion fit, color harmony, formality, season, pattern balance, versatility. - Include structured garment attributes (color, material, pattern, season, formality, description) per combo instead of description only. - Inject previously liked outfits as a style preference signal. - Sample diverse combos across tops when the list exceeds 40 items. - Use system+user messages, lower temperature (0.2), more tokens (1024). Co-authored-by: Cursor <cursoragent@cursor.com>63a6b7d -
fix(ui): restore garment images and descriptions in Ask chat
- Load wardrobe on Ask tab open and await loadWardrobe() on init so garment lookups are ready before the first question. - Build garmentsById map for reliable O(1) lookup with zero-padded IDs (garment_1 -> garment_001). - Replace garment references before markdown parsing using placeholders, matching both [garment_XXX] and bare garment_XXX forms. - Show AI-generated description in inline chips (fallback: color + type). - Instruct the assistant to always use bracketed [garment_XXX] IDs. Co-authored-by: Cursor <cursoragent@cursor.com>74e743a -
fix(ui): add bounds to rectangle geometry so detected boxes render
Annotorious v3 rectangle geometry requires a bounds field (minX, minY, maxX, maxY) in addition to x/y/w/h — its spatial index relies on it, so annotations without bounds were stored but never drawn. Compute bounds from each detected box. Co-authored-by: Cursor <cursoragent@cursor.com>1aafe24 -
fix(ui): use Annotorious v3 internal annotation format for bounding boxes
initAnnotator was building annotations in W3C FragmentSelector format which Annotorious v3 does not recognise as a drawable shape, so auto-detected boxes were never rendered. - Use the internal format: target.selector.type = 'RECTANGLE' with geometry {x, y, w, h} as documented in the Annotorious v3 API. - Remove the invalid `drawingTool` init option; call setDrawingTool() after instantiation instead. - Defer annotator creation until the <img> has finished loading (el.complete check + 'load' event listener) so the SVG layer has correct dimensions. - analyzeBoxes: read geometry directly from target.selector.geometry instead of parsing a FragmentSelector regex. Co-authored-by: Cursor <cursoragent@cursor.com>ba65e78 -
feat(ui): manual garment crop with Annotorious bounding-box editor
Upload a photo → server auto-detects garments via YOLOS and returns bounding boxes → Annotorious v3.8.6 renders the image with the boxes pre-drawn → user adds/edits/deletes boxes → "Analyse N garments" crops each box server-side and runs the VLM on each crop. Backend (app.py): - Mount data/_uploads/ as /uploads (temp image store). - api_prepare_image: saves upload, runs detect_garments, returns token + image_url + detected boxes [{x,y,w,h}]. - api_analyze_boxes: validates token, crops each box via PIL, calls extract_from_crop_bytes per crop, adds to catalog, cleans up. Frontend (index.html): - Load @annotorious/annotorious@3.8.6 CSS + ESM (version pinned). - handleFile now calls /prepare_image then opens the editor. - initAnnotator: creates annotator, loads initial boxes as W3C FragmentSelector annotations, syncs box count on create/delete. - analyzeBoxes: reads annotations, maps to pixel coords, calls /analyze_boxes, refreshes wardrobe on success. - cancelEditor: destroys an…2d97bc2 -
refactor(ui): show garment detail in a side drawer
Convert the garment detail from a centred modal to a right-aligned full-height side panel that slides in. Full-width on mobile. Co-authored-by: Cursor <cursoragent@cursor.com>7235725 -
fix(ui): log dock, garment detail layout and image cache
- Restore `-> dict` return annotation on api_load_dataset so Gradio serialises each generator yield as an SSE data event (logs were silently dropped without it). - Move log console to a fixed bottom dock (.log-dock) with a header showing live progress, a minimise/expand toggle and a close button; dock is visible from any tab during dataset loading. - Redesign garment detail panel as a single column with object-fit:contain image (no more distorted/cropped previews) and a clean attribute list below. - Add _image_url() helper with ?v=<mtime> query param to bust browser cache when the same garment ID is reused after clearing the catalog. - Call loadWardrobe() after a successful photo upload so the new garment appears immediately without a manual refresh. Co-authored-by: Cursor <cursoragent@cursor.com>4f4b1b3 -
feat(ui): garment detail panel and real-time load logs
- Clicking a wardrobe card opens an overlay with the full garment attributes (type, color, material, pattern, season, formality) and the AI-generated natural-language description. - api_load_dataset converted from a blocking call to a streaming generator that yields progress per garment (count, log lines, preview URL). - loadDataset() in the frontend now uses gradioClient.submit() to iterate SSE events; a live log console (dark monospace) and a row of thumbnail previews update in real time as each garment is processed. - Wardrobe is refreshed automatically once loading completes. Co-authored-by: Cursor <cursoragent@cursor.com>ee5ec33
-
perf(model): tune llama.cpp for cpu-basic
Set n_threads=2 when SPACE_ID is present to match 2 vCPU on CPU Basic. Update docstrings to reflect CPU Basic deployment instead of ZeroGPU. Co-authored-by: Cursor <cursoragent@cursor.com>632a1a3 -
fix(deploy): switch to CPU inference for ZeroGPU compatibility
ZeroGPU's CUDA emulation is PyTorch-specific — llama-cpp-python links directly against libcudart.so.12 which does not exist in the container. - Remove --extra-index-url cu124 (installs CPU-only llama-cpp-python) - Set python_version to 3.12 (ZeroGPU only supports 3.10/3.12) - Detect SPACE_ID to force n_gpu_layers=0 on HF Spaces - Remove @spaces.GPU from text-only LLM functions - Keep @spaces.GPU on detection functions (PyTorch YOLO benefits) - Add libopenblas-dev for CPU BLAS acceleration - Remove Python 3.13 unraisablehook patch (no longer needed) - Update README with local GPU install instructions All hackathon badges preserved: Off the Grid, Llama Champion, Tiny Titan. See docs/18-zerogpu-cpu-inference.md for full ADR. Co-authored-by: Cursor <cursoragent@cursor.com>4c7e762 -
fix (hf): use gpu from hf space
e7af96c -
chore (ui): Use new ui
6778432
-
feat(combinations): add context-aware LLM ranking for outfits
Allow users to describe an occasion (e.g. "dinner on a terrace, summer") and have the LLM re-rank outfit combinations for that specific context. - rank_combinations_prompt() now accepts optional context parameter - New rank_with_llm() function calls LLM and parses ranked response - Robust JSON parsing with regex fallback for outfit IDs Co-authored-by: Cursor <cursoragent@cursor.com>b269444 -
refactor(detector): replace monolithic detector with pluggable multi-backend package
Replace src/detector.py with src/detector/ package featuring: - Separated interface: detect_garments() returns BoundingBox list, crop_garments() handles PIL cropping independently - Registry pattern: backends self-register via @register decorator - Three backends: yolos (YOLOS-tiny/HF), yolov8 (ultralytics), grounding_dino (open vocabulary, prompt-based) - is_available() per backend for graceful degradation Redesign Capture tab: - image_annotator always visible as primary input - Two coexisting buttons: auto-detect and manual selection - Settings accordion to switch detection backend at runtime Add src/settings.py for JSON-persisted runtime configuration. Co-authored-by: Cursor <cursoragent@cursor.com>746317a -
feat(ui): add manual bbox annotation fallback when detection fails
When YOLOS detects 0 garments in multi mode, the UI shows a gradio-image-annotation-v2 widget for manual bounding box selection. User draws rectangles over visible garments and clicks "Procesar selección" — crops are sent to the VLM for attribute extraction. - Add gradio-image-annotation-v2 dependency - New process_manual_boxes() handler in app.py - New extract_from_crop_bytes() in vision.py - analyze_images() now returns annotator state on detection failure Co-authored-by: Cursor <cursoragent@cursor.com>5be2181 -
refactor(detector): replace YOLOv8n with YOLOS-tiny for flat lay support
Replace kesimeg/yolov8n-clothing-detection (ultralytics) with yainage90/fashion-object-detection-yolos-tiny (transformers): - Trained on modanet + fashionpedia (includes flat lay images) - 6.47M params, mAP 0.697 - Labels: bag, bottom, dress, hat, shoes, outer, top - Runs on CPU via torch.no_grad() - Swap ultralytics dep for transformers + torch in requirements Co-authored-by: Cursor <cursoragent@cursor.com>147c5f0 -
feat(ui): add capture mode selector (single/multi/video WIP)
Add a Radio selector in the Capture tab with three modes: - Single garment: skips YOLO, sends photo directly to VLM with single-garment prompt (ideal for close-up photos) - Multiple garments: full pipeline (YOLO + crops + VLM per crop, fallback to multi-garment VLM analysis) - Video stream: placeholder showing "coming soon" message New vision.extract_single_from_path() for direct single-garment extraction without YOLO detection step. Co-authored-by: Cursor <cursoragent@cursor.com>ba65fe9 -
fix(detector): lower confidence threshold to 0.15
The previous threshold (0.35) caused YOLO to miss garments in flat lay photos. Lowering to 0.15 improves detection on product-style images while the fallback handles any remaining misses. Co-authored-by: Cursor <cursoragent@cursor.com>12e8038 -
fix(detector): download YOLO model from HuggingFace before loading
YOLO() does not accept HuggingFace repo IDs directly. Use hf_hub_download() to fetch the .pt file first, then pass the local path to YOLO(). The model file is 'best.pt' (standard ultralytics fine-tune convention). Co-authored-by: Cursor <cursoragent@cursor.com>a2fc99b -
fix(catalog): ensure data persists across app restarts
- Use Path.resolve() for all data paths to avoid symlink/CWD issues - Call _format_catalog_stats() with parens at Gradio build time so the stats Markdown evaluates immediately (not deferred) - Add startup log confirming catalog load count - Add debug logging to load_catalog() for troubleshooting Co-authored-by: Cursor <cursoragent@cursor.com>913537b -
refactor(vision): use detector crops for per-garment extraction
Rewrite the vision pipeline to use YOLO-detected crops: - Each crop is sent individually to the VLM (focused single-garment prompt yields better results than multi-garment from full image) - extract_garments() now returns list[tuple[dict, bytes]] where each garment has its own unique crop bytes - catalog.add_garments() updated to accept per-garment image bytes - Falls back to full-image analysis when YOLO detects nothing - Add single-object JSON parsing to handle VLM responses for crops Co-authored-by: Cursor <cursoragent@cursor.com>226ca6c -
feat(detector): add YOLOv8n garment detection and cropping
New module src/detector.py that uses YOLOv8 Nano (fine-tuned on Fashionpedia) to detect garment bounding boxes in images. Runs on CPU to avoid VRAM contention with the VLM. Each detection is cropped with PIL and returned as JPEG bytes for individual garment analysis. Adds ultralytics dependency to requirements.txt. Co-authored-by: Cursor <cursoragent@cursor.com>73c2744 -
feat(combinations): add outfit combination engine
New module src/combinations.py with: - Garment classification into tops/bottoms categories - Rules-based filtering (season + formality compatibility) - LLM ranking prompt generation for style scoring - Outfit preference persistence (like/dislike in data/outfits.json) - Disliked combinations excluded from future suggestions Co-authored-by: Cursor <cursoragent@cursor.com>727dd4f -
feat(vision): add verbose description to garment extraction
- Extend VLM prompt to request a 1-2 sentence natural language description per garment (style, fit, notable details) - Include description field in garment normalization - Update get_catalog_summary() to show descriptions in LLM context, improving outfit recommendation quality Co-authored-by: Cursor <cursoragent@cursor.com>6ca17ee -
feat(catalog): add image persistence per garment
- vision.py now returns (garments, image_bytes) from extract_garments() - catalog.add_garments() accepts image_bytes and saves a thumbnail per garment via the storage layer - Each garment gets an image_ref field pointing to its stored image - clear_catalog() now also removes associated images - app.py passes image bytes through the full pipeline Co-authored-by: Cursor <cursoragent@cursor.com>14e7ce6 -
feat(storage): add dual storage abstraction (local/S3)
Add src/storage.py with two backends: - local: writes to data/garments/ (default for development) - s3: uses HF Spaces S3 bucket (for production persistence) Backend is selected via STORAGE_BACKEND env var. Includes .env.example with all configurable variables documented. Co-authored-by: Cursor <cursoragent@cursor.com>edbf640 -
feat(wardrobe): implement vision pipeline, catalog and assistant
- Add VLM-based garment extraction with Gemma 3 4B (src/vision.py) - Add JSON catalog storage with search and stats (src/catalog.py) - Add context-injected assistant with streaming (src/assistant.py) - Add singleton model loader with VRAM management (src/model_loader.py) - Implement 3-tab Gradio UI (Capture, Wardrobe, Chat) - Update shootout script for Gemma 3 4B handler Co-authored-by: Cursor <cursoragent@cursor.com>75e0882
-
feat (wardrobe): prepare project structure and basic gradio ui
cb7a01c